Merge branch 'master' into yijianlian
# Conflicts: # app/src/main/java/com/yingmao/clash/act/ChangeNodeActivity.kt # app/src/main/java/com/yingmao/clash/act/LoginActivity.kt # app/src/main/java/com/yingmao/clash/act/MainActivity.kt # app/src/main/java/com/yingmao/clash/act/MemberRechargeActivity.kt # app/src/main/java/com/yingmao/clash/act/NewMainActivity.kt # app/src/main/java/com/yingmao/clash/act/SettingActivity.kt # app/src/main/java/com/yingmao/clash/act/SplashActivity.kt # app/src/main/java/com/yingmao/clash/app/MainApplication.kt # app/src/main/java/com/yingmao/clash/base/BaseActivity.kt # app/src/main/java/com/yingmao/clash/base/BaseViewMode.kt # app/src/main/java/com/yingmao/clash/fragment/NewAccFragment.kt # app/src/main/java/com/yingmao/clash/fragment/home/HomeFragment.kt # app/src/main/java/com/yingmao/clash/fragment/recharge/RechargeFragment.kt # app/src/main/java/com/yingmao/clash/fragment/setting/SettingFragment.kt # app/src/main/java/com/yingmao/clash/net/http/HttpApi.kt # app/src/main/java/com/yingmao/clash/service/ConnectionService.java # app/src/main/java/com/yingmao/clash/vm/MainAtyVM.kt # app/src/main/res/values-en/strings.xml # app/src/main/res/values-zh-rHK/strings.xml # app/src/main/res/values-zh-rTW/strings.xml # app/src/main/res/values/strings.xml # build.gradle.kts # gradle/wrapper/gradle-wrapper.properties
This commit is contained in:
commit
d9d32a31a6
|
|
@ -101,10 +101,7 @@
|
||||||
android:name=".act.RegisterActivity"
|
android:name=".act.RegisterActivity"
|
||||||
android:process=":background"
|
android:process=":background"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
|
||||||
android:name=".act.NewMainActivity"
|
|
||||||
android:process=":background"
|
|
||||||
android:screenOrientation="portrait" />
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".act.LoginActivity"
|
android:name=".act.LoginActivity"
|
||||||
android:process=":background"
|
android:process=":background"
|
||||||
|
|
@ -113,9 +110,7 @@
|
||||||
android:name=".webview.BZYWebViewActivity"
|
android:name=".webview.BZYWebViewActivity"
|
||||||
android:process=":background"
|
android:process=":background"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
|
||||||
android:name=".act.MyPointCardActivity"
|
|
||||||
android:screenOrientation="portrait" />
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".act.ShareActivity"
|
android:name=".act.ShareActivity"
|
||||||
android:process=":background"
|
android:process=":background"
|
||||||
|
|
@ -123,9 +118,7 @@
|
||||||
<activity
|
<activity
|
||||||
android:name=".act.BandPhoneActivity"
|
android:name=".act.BandPhoneActivity"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
|
||||||
android:name=".act.ZFBTXActivity"
|
|
||||||
android:screenOrientation="portrait" />
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".webview.BZYWebViewOther"
|
android:name=".webview.BZYWebViewOther"
|
||||||
android:process=":background"
|
android:process=":background"
|
||||||
|
|
|
||||||
|
|
@ -250,15 +250,16 @@ class ChangeNodeActivity : BaseActivity(), View.OnClickListener {
|
||||||
Log.d("ChangeNode22 uuid==>${profile.uuid}")
|
Log.d("ChangeNode22 uuid==>${profile.uuid}")
|
||||||
if (isDelete) {
|
if (isDelete) {
|
||||||
Log.d("gogogogogo isDelete")
|
Log.d("gogogogogo isDelete")
|
||||||
profileManager.delete(profile.uuid)
|
// profileManager.delete(profile.uuid)
|
||||||
MMKV.defaultMMKV()
|
MMKV.defaultMMKV()
|
||||||
.removeValueForKey(BZYConstants.NODE_All_ITEM_NAME_KEY)
|
.removeValueForKey(BZYConstants.NODE_All_ITEM_NAME_KEY)
|
||||||
setSub2(profileManager, nowSubUrl)
|
|
||||||
} else {
|
} else {
|
||||||
Log.d("gogogogogo update")
|
Log.d("gogogogogo update")
|
||||||
profileManager.setActive(profile)
|
profileManager.setActive(profile)
|
||||||
delay(500)
|
Log.d("updateProfile pro.source==>${profile.source}, url==>${nowSubUrl}")
|
||||||
if (!TextUtils.isEmpty(profile.source)) {
|
if (!TextUtils.isEmpty(profile.source)) {
|
||||||
|
|
||||||
if (profile.source != nowSubUrl) {
|
if (profile.source != nowSubUrl) {
|
||||||
Log.d("updateProfile patch")
|
Log.d("updateProfile patch")
|
||||||
profileManager.patch(
|
profileManager.patch(
|
||||||
|
|
@ -273,6 +274,17 @@ class ChangeNodeActivity : BaseActivity(), View.OnClickListener {
|
||||||
}
|
}
|
||||||
Log.d("updateProfile patch 2")
|
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")
|
Log.d("updateProfile go update")
|
||||||
profileManager.update(profile.uuid)
|
profileManager.update(profile.uuid)
|
||||||
|
|
@ -375,7 +387,6 @@ class ChangeNodeActivity : BaseActivity(), View.OnClickListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun setNewData(nodes: MutableList<ClashNodebBean>?) {
|
private fun setNewData(nodes: MutableList<ClashNodebBean>?) {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
if (nodes != null) {
|
if (nodes != null) {
|
||||||
|
|
|
||||||
|
|
@ -31,13 +31,12 @@ import com.cncat.vpn.common.log.Log
|
||||||
import com.yingmao.clash.conf.BZYConstants
|
import com.yingmao.clash.conf.BZYConstants
|
||||||
import com.yingmao.clash.conf.Conf
|
import com.yingmao.clash.conf.Conf
|
||||||
import com.yingmao.clash.entity.ClashNodebBean
|
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.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.app.MainApplication
|
||||||
|
import com.yingmao.clash.fragment.home.HomeFragment
|
||||||
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
|
||||||
|
|
@ -92,7 +91,7 @@ class ChangeNodeTzActivity : BaseActivity(), View.OnClickListener {
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
intent.putExtra(BZYConstants.EXTRA_KEY_IS_RUNING, is_runing)
|
intent.putExtra(BZYConstants.EXTRA_KEY_IS_RUNING, is_runing)
|
||||||
setResult(CHECK_NODE_RESULT_CODE, intent)
|
setResult(HomeFragment.CHECK_NODE_RESULT_CODE, intent)
|
||||||
super.onBackPressed()
|
super.onBackPressed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -337,7 +336,7 @@ class ChangeNodeTzActivity : BaseActivity(), View.OnClickListener {
|
||||||
|
|
||||||
val reloadLock = Semaphore(10)
|
val reloadLock = Semaphore(10)
|
||||||
private fun setPing() {
|
private fun setPing() {
|
||||||
if (!NewAccFragment.clashRunning) {
|
if (!HomeFragment.clashRunning) {
|
||||||
RxToast.info("请先开启加速后,再进行测试.");
|
RxToast.info("请先开启加速后,再进行测试.");
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -430,7 +429,7 @@ class ChangeNodeTzActivity : BaseActivity(), View.OnClickListener {
|
||||||
val intent = Intent()
|
val intent = Intent()
|
||||||
intent.putExtra(BZYConstants.MMKV_KEY_SELECT_NODE_NAME, "自动选择")
|
intent.putExtra(BZYConstants.MMKV_KEY_SELECT_NODE_NAME, "自动选择")
|
||||||
intent.putExtra(BZYConstants.EXTRA_KEY_IS_RUNING, is_runing)
|
intent.putExtra(BZYConstants.EXTRA_KEY_IS_RUNING, is_runing)
|
||||||
setResult(CHECK_NODE_RESULT_CODE, intent)
|
setResult(HomeFragment.CHECK_NODE_RESULT_CODE, intent)
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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("查询点卡余额异常")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -496,34 +496,23 @@ class NewMainActivity : BaseActivity() {
|
||||||
val lastNotice =
|
val lastNotice =
|
||||||
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_NOTICE_READ, "")
|
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_NOTICE_READ, "")
|
||||||
val data = it.data
|
val data = it.data
|
||||||
|
// if (data?.notice != null) {
|
||||||
|
// initMainPageHorseRaceLamp(data.notice)
|
||||||
|
// }
|
||||||
if (data?.notice != null && lastNotice != data.notice) {
|
if (data?.notice != null && lastNotice != data.notice) {
|
||||||
val notice = data.notice
|
val notice = data.notice!!
|
||||||
MaterialDialog(this).show {
|
val dialog = DialogNotice(this@NewMainActivity, notice, data.downloadUrl)
|
||||||
this.cancelable(false)
|
dialog.setOnReadClickListener(object : DialogNotice.OnReadClickListener {
|
||||||
cornerRadius(res = R.dimen.dp_10)
|
override fun onReadClick() {
|
||||||
customView(
|
|
||||||
R.layout.dialog_notice_layout,
|
|
||||||
scrollable = false,
|
|
||||||
noVerticalPadding = true,
|
|
||||||
horizontalPadding = false
|
|
||||||
)
|
|
||||||
val noticeContent = getCustomView().findViewById<TextView>(R.id.tv_notice_content)
|
|
||||||
noticeContent.text=notice
|
|
||||||
noticeContent.movementMethod = LinkMovementMethod.getInstance()
|
|
||||||
|
|
||||||
val noticeUrl = getCustomView().findViewById<TextView>(R.id.tv_notice_url)
|
|
||||||
noticeUrl.text= context.resources.getString(R.string.ClientDownload)+"\n${data.downloadUrl}"
|
|
||||||
|
|
||||||
getCustomView().findViewById<TextView>(R.id.tv_sure).setOnClickListener {
|
|
||||||
MMKV.defaultMMKV()
|
MMKV.defaultMMKV()
|
||||||
.encode(BZYConstants.MMKV_KEY_NOTICE_READ, data.notice)
|
.encode(BZYConstants.MMKV_KEY_NOTICE_READ, data.notice!!)
|
||||||
MMKV.defaultMMKV().encode(
|
MMKV.defaultMMKV().encode(
|
||||||
BZYConstants.MMKV_KEY_NOTICE_DOWNLOAD_READ, data.downloadUrl
|
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_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<NewAccFragment>().forEach {
|
fragments.filterIsInstance<NewAccFragment>().forEach { it.setExpireDate() }
|
||||||
it.setExpireDate()
|
|
||||||
it.changeUserState()
|
|
||||||
}
|
|
||||||
checkPayResultDia?.dismiss()
|
checkPayResultDia?.dismiss()
|
||||||
mainAtyVM.getAirNodes()
|
mainAtyVM.getAirNodes()
|
||||||
RxToast.info(resources.getString(R.string.SuccessfullyUpdatedUserInformation))
|
RxToast.info(resources.getString(R.string.SuccessfullyUpdatedUserInformation))
|
||||||
mainAtyVM.getExpensesRecord(mPageInfo)
|
|
||||||
} else {
|
} else {
|
||||||
// RxToast.info(resources.getString(R.string.PaymentResultsStr))
|
// RxToast.info(resources.getString(R.string.PaymentResultsStr))
|
||||||
}
|
}
|
||||||
} else if(checkLoginRsp.code == -2){
|
} else {
|
||||||
RxToast.info(resources.getString(R.string.LoginOut))
|
|
||||||
cleanUserInfoToLogout()
|
|
||||||
}else{
|
|
||||||
RxToast.info(resources.getString(R.string.QueryFailed))
|
RxToast.info(resources.getString(R.string.QueryFailed))
|
||||||
}
|
}
|
||||||
payResultLoading?.dismiss()
|
payResultLoading?.dismiss()
|
||||||
|
|
@ -590,25 +572,26 @@ class NewMainActivity : BaseActivity() {
|
||||||
} else {
|
} else {
|
||||||
RxToast.error(resources.getString(R.string.NodeAcquisitionFailed) + "${data.msg}")
|
RxToast.error(resources.getString(R.string.NodeAcquisitionFailed) + "${data.msg}")
|
||||||
}
|
}
|
||||||
data.data.let { url ->
|
data.data?.let { url ->
|
||||||
android.util.Log.e("Data", "机场URL:=${url}")
|
android.util.Log.e("Data", "机场URL:=${url}")
|
||||||
// var url2="https://api.ymvpnpro11.cc:8700/7air2vr7ikiqzgvxz/api/v1/client/subscribe?token=5af82930d222840cbc2dec572b21d6c6"
|
// var url2="https://api.ymvpnpro11.cc:8700/7air2vr7ikiqzgvxz/api/v1/client/subscribe?token=5af82930d222840cbc2dec572b21d6c6"
|
||||||
if (url.isNotEmpty()) {
|
if (url.isNotEmpty()) {
|
||||||
//todo 判断订阅地址是否修改过,未修改就用接口返回的地址反之使用本地修改的地址
|
//todo 判断订阅地址是否修改过,未修改就用接口返回的地址反之使用本地修改的地址
|
||||||
val proSubUrl =
|
var pro_sub_url =
|
||||||
MMKV.defaultMMKV().decodeString(BZYConstants.PROFILE_SUB_URL, "")
|
MMKV.defaultMMKV().decodeString(BZYConstants.PROFILE_SUB_URL, "")
|
||||||
if (!TextUtils.isEmpty(proSubUrl)){
|
if (!TextUtils.isEmpty(pro_sub_url)) {
|
||||||
if (proSubUrl == url) {
|
if (pro_sub_url == url) {
|
||||||
subUrl = url
|
subUrl = url
|
||||||
} else {
|
} else {
|
||||||
subUrl = proSubUrl
|
subUrl = pro_sub_url
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
subUrl = url
|
subUrl = url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
// setSub(url)
|
||||||
subUrl?.let { setSub2(it) }
|
subUrl?.let { setSub2(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -631,149 +614,31 @@ class NewMainActivity : BaseActivity() {
|
||||||
} else if (httpStatus.reqType == HttpReqType.GetActivity) {
|
} else if (httpStatus.reqType == HttpReqType.GetActivity) {
|
||||||
val data = httpStatus.rsp as GetActivityRsp
|
val data = httpStatus.rsp as GetActivityRsp
|
||||||
if (data.code == 200) {
|
if (data.code == 200) {
|
||||||
if (data.data.data.list.isNotEmpty()) {
|
if (data.data != null) {
|
||||||
if(data.data.data.list.size>1){
|
if (data.data.data != null) {
|
||||||
val bannerImgBeans=mutableListOf<BannerImgBean>()
|
if (data.data.data.list.isNotEmpty()) {
|
||||||
data.data.data.list.forEach {item->
|
data.data.data.list[0].redirectLink.let {
|
||||||
bannerImgBeans.add(BannerImgBean(item.title,item.content,item.redirectLink,0))
|
if(activityDialog==null){
|
||||||
}
|
activityDialog =
|
||||||
homeActivityDialog = HomeActivityDialog(this,bannerImgBeans)
|
ActivityViewDialog(this, data.data.data.list[0].redirectLink)
|
||||||
homeActivityDialog!!.show()
|
activityDialog?.setOnDialogClickListener(object :
|
||||||
homeActivityDialog?.setOnDialogClickListener(object : HomeActivityDialog.OnHADialogClickListener {
|
OnDialogClickListener {
|
||||||
override fun onRechargeClickListener() {
|
override fun onRechargeClickListener() {
|
||||||
//跳转到支付界面
|
//跳转到支付界面
|
||||||
goBackupRechargeWeb()
|
goBackupRechargeWeb()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCancelClickListener() {
|
override fun onCancelClickListener() {
|
||||||
homeActivityDialog?.dismiss()
|
activityDialog?.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)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
dialog.show()
|
activityDialog?.show()
|
||||||
}else if(bannerImgBeans.get(position).redirectLink.contains("SignIn")){
|
|
||||||
mainAtyVM.vipSign()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}else{
|
|
||||||
data.data.data.list[0].redirectLink.let {
|
|
||||||
var bannerImgBeans=mutableListOf<BannerImgBean>()
|
|
||||||
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<ConstraintLayout>(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())
|
// fragments.add(RechargeFragment())
|
||||||
containerVP.adapter = MainVPAdapter(fragments, supportFragmentManager, lifecycle)
|
containerVP.adapter = MainVPAdapter(fragments, supportFragmentManager, lifecycle)
|
||||||
containerVP.isUserInputEnabled = false
|
containerVP.isUserInputEnabled = false
|
||||||
clHomeRecharge=findViewById(R.id.clHomeRecharge)
|
var aniAct = findViewById<LottieAnimationView>(R.id.lottie_activity)
|
||||||
clDeepSeek=findViewById(R.id.clDeepSeek)
|
aniAct.setAnimation(R.raw.activity)
|
||||||
floating=findViewById(R.id.floating)
|
aniAct.playAnimation()
|
||||||
tv_exit=findViewById(R.id.tv_exit)
|
aniAct.setOnClickListener {
|
||||||
clSing=findViewById(R.id.clSing)
|
startActivity(Intent(CommonUtils.getApp(), ActivityActivity::class.java))
|
||||||
clSing.setOnClickListener {
|
|
||||||
mainAtyVM.vipSign()
|
|
||||||
}
|
}
|
||||||
|
findViewById<LinearLayout>(R.id.ll_activity).setOnClickListener {
|
||||||
clHomeRecharge.setOnClickListener {
|
startActivity(Intent(CommonUtils.getApp(), ActivityActivity::class.java))
|
||||||
goBackupRechargeWeb()
|
|
||||||
}
|
|
||||||
tv_exit.setOnClickListener {
|
|
||||||
cleanUserInfo()
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
clDeepSeek.setOnClickListener {
|
|
||||||
startActivity(Intent(this, CustomerServiceWebView::class.java))
|
|
||||||
drawer.close()
|
|
||||||
}
|
|
||||||
floating.setOnClickListener {
|
|
||||||
startActivity(Intent(this, CustomerServiceWebView::class.java))
|
|
||||||
}
|
}
|
||||||
setSometion()
|
setSometion()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initMainPageHorseRaceLamp(noticeData: String) {
|
private fun initMainPageHorseRaceLamp(noticeData: String) {
|
||||||
|
val mainPageHorseRaceLamp = findViewById<TextView>(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<LinearLayout>(R.id.llNoticeBackground)
|
||||||
|
llNoticeBackground.visibility = View.GONE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun cleanUserInfo() {
|
private fun cleanUserInfo() {
|
||||||
|
|
@ -849,9 +713,6 @@ class NewMainActivity : BaseActivity() {
|
||||||
MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_SELECTED_NAME_KEY)
|
MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_SELECTED_NAME_KEY)
|
||||||
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_VPN_UserCommand)
|
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_VPN_UserCommand)
|
||||||
MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_All_ITEM_NAME_KEY)
|
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}")
|
Log.d("cleanUserInfo clashRunning==>${clashRunning}")
|
||||||
if (clashRunning) {
|
if (clashRunning) {
|
||||||
fragments.filterIsInstance<NewAccFragment>().forEach { it.stopClash() }
|
fragments.filterIsInstance<NewAccFragment>().forEach { it.stopClash() }
|
||||||
|
|
@ -862,28 +723,6 @@ class NewMainActivity : BaseActivity() {
|
||||||
startActivity(Intent(CommonUtils.getApp(), LoginActivity::class.java))
|
startActivity(Intent(CommonUtils.getApp(), LoginActivity::class.java))
|
||||||
finish()
|
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<NewAccFragment>().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() {
|
private fun cleanProfile() {
|
||||||
|
|
@ -906,11 +745,25 @@ class NewMainActivity : BaseActivity() {
|
||||||
tv_username = findViewById(R.id.tv_username)
|
tv_username = findViewById(R.id.tv_username)
|
||||||
iv_slider = findViewById(R.id.iv_slider)
|
iv_slider = findViewById(R.id.iv_slider)
|
||||||
ll_slider = findViewById(R.id.ll_slider)
|
ll_slider = findViewById(R.id.ll_slider)
|
||||||
|
tv_exit = findViewById(R.id.tv_exit)
|
||||||
tv_band = findViewById(R.id.tv_band)
|
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<TextView>(R.id.tv_version).text =
|
findViewById<TextView>(R.id.tv_version).text =
|
||||||
resources.getString(R.string.edition) + "${BuildConfig.VERSION_NAME}." + BuildConfig.productId
|
resources.getString(R.string.edition) + "${BuildConfig.VERSION_NAME}." + BuildConfig.productId
|
||||||
|
|
||||||
if (MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_IS_PERFECT)) {
|
if (MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_IS_PERFECT)) {
|
||||||
|
// 临时用户显示默认密码
|
||||||
|
// findViewById<TextView>(R.id.tv_default_psw).visibility = View.VISIBLE
|
||||||
tv_band.setOnClickListener {//绑定
|
tv_band.setOnClickListener {//绑定
|
||||||
showBingDialogChoose()
|
showBingDialogChoose()
|
||||||
drawer.close()
|
drawer.close()
|
||||||
|
|
@ -924,37 +777,35 @@ class NewMainActivity : BaseActivity() {
|
||||||
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
|
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
|
||||||
}"
|
}"
|
||||||
}
|
}
|
||||||
findViewById<ConstraintLayout>(R.id.clRecharge).setOnClickListener {//充值
|
|
||||||
|
tv_exit.setOnClickListener {//退出
|
||||||
|
cleanUserInfo()
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
findViewById<TextView>(R.id.tv_viprecharge).setOnClickListener {//充值
|
||||||
|
// tv_rechar.visibility = View.GONE
|
||||||
|
// iv_slider.setImageResource(R.drawable.ic_s_back)
|
||||||
|
drawer.close()
|
||||||
|
goBackupRechargeWeb()
|
||||||
|
}
|
||||||
|
findViewById<TextView>(R.id.tv_vip_recharge).setOnClickListener {
|
||||||
drawer.close()
|
drawer.close()
|
||||||
goBackupRechargeWeb()
|
goBackupRechargeWeb()
|
||||||
}
|
}
|
||||||
|
|
||||||
findViewById<ConstraintLayout>(R.id.clNotice).setOnClickListener {//通知
|
findViewById<TextView>(R.id.tv_notice).setOnClickListener {//通知
|
||||||
val notice =
|
val notice =
|
||||||
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_NOTICE_READ, "暂无新通知")!!
|
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_NOTICE_READ, "暂无新通知")!!
|
||||||
val downloadUrl =
|
val download_url =
|
||||||
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_NOTICE_DOWNLOAD_READ, "")!!
|
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_NOTICE_DOWNLOAD_READ, "")!!
|
||||||
MaterialDialog(this).show {
|
val dialog = DialogNotice(this@NewMainActivity, notice, download_url)
|
||||||
this.cancelable(false)
|
dialog.setOnReadClickListener(object : DialogNotice.OnReadClickListener {
|
||||||
cornerRadius(res = R.dimen.dp_10)
|
override fun onReadClick() {
|
||||||
customView(
|
dialog.dismiss()
|
||||||
R.layout.dialog_notice_layout,
|
|
||||||
scrollable = false,
|
|
||||||
noVerticalPadding = true,
|
|
||||||
horizontalPadding = false
|
|
||||||
)
|
|
||||||
val noticeContent = getCustomView().findViewById<TextView>(R.id.tv_notice_content)
|
|
||||||
noticeContent.text=notice
|
|
||||||
noticeContent.movementMethod = LinkMovementMethod.getInstance()
|
|
||||||
|
|
||||||
val noticeUrl = getCustomView().findViewById<TextView>(R.id.tv_notice_url)
|
|
||||||
noticeUrl.text= context.resources.getString(R.string.ClientDownload)+"\n${downloadUrl}"
|
|
||||||
|
|
||||||
getCustomView().findViewById<TextView>(R.id.tv_sure).setOnClickListener {
|
|
||||||
dismiss()
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
dialog.show()
|
||||||
drawer.close()
|
drawer.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -965,43 +816,68 @@ class NewMainActivity : BaseActivity() {
|
||||||
clipboardManager.setPrimaryClip(clipData)
|
clipboardManager.setPrimaryClip(clipData)
|
||||||
RxToast.info(resources.getString(R.string.CopyToClipboard))
|
RxToast.info(resources.getString(R.string.CopyToClipboard))
|
||||||
}
|
}
|
||||||
findViewById<ConstraintLayout>(R.id.clShare).setOnClickListener {//分享
|
|
||||||
|
// tv_rechar.setOnClickListener {
|
||||||
|
// goRechargeWeb()
|
||||||
|
// }
|
||||||
|
findViewById<TextView>(R.id.tv_share).setOnClickListener {//分享
|
||||||
startActivity(Intent(this@NewMainActivity, ShareActivity::class.java))
|
startActivity(Intent(this@NewMainActivity, ShareActivity::class.java))
|
||||||
drawer.close()
|
drawer.close()
|
||||||
}
|
}
|
||||||
findViewById<ConstraintLayout>(R.id.clSetting).setOnClickListener {//设置
|
findViewById<TextView>(R.id.tv_setting).setOnClickListener {//设置
|
||||||
startActivity(Intent(this, SettingActivity::class.java))
|
startActivity(Intent(this, SettingActivity::class.java))
|
||||||
drawer.close()
|
drawer.close()
|
||||||
}
|
}
|
||||||
|
findViewById<TextView>(R.id.tv_dianka).setOnClickListener {//点卡
|
||||||
|
startActivity(Intent(this, MyPointCardActivity::class.java))
|
||||||
|
drawer.close()
|
||||||
|
}
|
||||||
|
findViewById<TextView>(R.id.tv_vip_sign).setOnClickListener {//会员签到
|
||||||
|
mainAtyVM.vipSign()
|
||||||
|
// drawer.close()
|
||||||
|
}
|
||||||
|
findViewById<TextView>(R.id.tv_tixian).setOnClickListener {//提现
|
||||||
|
startActivity(Intent(this, ZFBTXActivity::class.java))
|
||||||
|
drawer.close()
|
||||||
|
}
|
||||||
|
val telegramBtn = findViewById<TextView>(R.id.tv_dianbao)
|
||||||
|
|
||||||
findViewById<ConstraintLayout>(R.id.clLocation).setOnClickListener {//变更
|
telegramBtn.setOnClickListener {//电报
|
||||||
if (checkExpire()) {
|
var uri = Uri.parse(BZYConstants.DefTGUrl)
|
||||||
RxToast.info(resources.getString(R.string.AccountExpired))
|
val intent = Intent(Intent.ACTION_VIEW)
|
||||||
return@setOnClickListener
|
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)
|
intent.setData(uri)
|
||||||
if (!TextUtils.isEmpty(newUuid)) {
|
startActivity(intent)
|
||||||
intent.putExtra(BZYConstants.MMKV_KEY_CURRENT_NODE, newUuid)
|
|
||||||
intent.putExtra(BZYConstants.EXTRA_KEY_IS_RUNING, clashRunning)
|
|
||||||
}
|
|
||||||
startActivityForResult(intent, CHECK_NODE_REQUEST_CODE)
|
|
||||||
drawer.close()
|
drawer.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
findViewById<ConstraintLayout>(R.id.clActivity).setOnClickListener {//活动
|
findViewById<TextView>(R.id.tv_kefu).setOnClickListener {//客服
|
||||||
startActivity(Intent(this, ActivityActivity::class.java))
|
startActivity(Intent(this, BZYWebViewKeFu::class.java))
|
||||||
drawer.close()
|
|
||||||
}
|
|
||||||
findViewById<ConstraintLayout>(R.id.clAccount).setOnClickListener {
|
|
||||||
startActivity(Intent(this, MineInfoActivity::class.java))
|
|
||||||
drawer.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
findViewById<ConstraintLayout>(R.id.clKf).setOnClickListener {//客服
|
|
||||||
startActivity(Intent(this, CustomerServiceWebView::class.java))
|
|
||||||
drawer.close()
|
drawer.close()
|
||||||
}
|
}
|
||||||
|
var fds_view = findViewById<TextView>(R.id.tv_fds);
|
||||||
|
fds_view.setOnClickListener {//防丢失
|
||||||
|
startActivity(Intent(this, LossPreventionActivity::class.java))
|
||||||
|
|
||||||
|
drawer.close()
|
||||||
|
}
|
||||||
drawer = findViewById(R.id.drawer)
|
drawer = findViewById(R.id.drawer)
|
||||||
iv_slider.setOnClickListener {
|
iv_slider.setOnClickListener {
|
||||||
if (containerVP.currentItem != 0) {
|
if (containerVP.currentItem != 0) {
|
||||||
|
|
@ -1011,6 +887,10 @@ class NewMainActivity : BaseActivity() {
|
||||||
drawer.openDrawer(GravityCompat.START)
|
drawer.openDrawer(GravityCompat.START)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (BuildConfig.is_tz && BuildConfig.productId == "182269") {
|
||||||
|
telegramBtn.visibility = View.INVISIBLE
|
||||||
|
fds_view.visibility = View.INVISIBLE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var checkPayResultDia: MaterialDialog? = null
|
var checkPayResultDia: MaterialDialog? = null
|
||||||
|
|
@ -1032,7 +912,7 @@ class NewMainActivity : BaseActivity() {
|
||||||
public fun goBackupRechargeWeb() {
|
public fun goBackupRechargeWeb() {
|
||||||
|
|
||||||
startActivityForResult(
|
startActivityForResult(
|
||||||
Intent(this@NewMainActivity, MemberRechargeActivity::class.java),
|
Intent(this@NewMainActivity, BackupRechargeActivity::class.java),
|
||||||
REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY
|
REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -1072,6 +952,7 @@ class NewMainActivity : BaseActivity() {
|
||||||
|
|
||||||
checkBindAccountDia = MaterialDialog(this).show {
|
checkBindAccountDia = MaterialDialog(this).show {
|
||||||
this.cancelable(false)
|
this.cancelable(false)
|
||||||
|
cornerRadius(res = R.dimen.dp_10)
|
||||||
customView(
|
customView(
|
||||||
R.layout.bind_account_dialog_layout,
|
R.layout.bind_account_dialog_layout,
|
||||||
scrollable = false,
|
scrollable = false,
|
||||||
|
|
@ -1101,6 +982,9 @@ class NewMainActivity : BaseActivity() {
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var payResultLoading: RxDialogShapeLoading? = null
|
||||||
|
private var timerJob: Job? = null
|
||||||
|
private var loadingTimeoutNum = 3
|
||||||
private fun showLoadingDialog(msg: String) {
|
private fun showLoadingDialog(msg: String) {
|
||||||
payResultLoading = RxDialogShapeLoading(this)
|
payResultLoading = RxDialogShapeLoading(this)
|
||||||
payResultLoading!!.setMessage(msg)
|
payResultLoading!!.setMessage(msg)
|
||||||
|
|
@ -1313,42 +1197,97 @@ class NewMainActivity : BaseActivity() {
|
||||||
}
|
}
|
||||||
startActivity(intent)
|
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?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
|
|
||||||
if (requestCode == REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY) {
|
if (requestCode == REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY) {
|
||||||
if (activityDialog != null) {
|
if (activityDialog != null) {
|
||||||
activityDialog?.dismiss()
|
activityDialog?.dismiss()
|
||||||
}
|
}
|
||||||
goCheckLogin()
|
goCheckLogin()
|
||||||
showBindAccount()
|
showBindAccount()
|
||||||
}else if(requestCode == CHECK_NODE_REQUEST_CODE){
|
|
||||||
fragments.filterIsInstance<NewAccFragment>().forEach { it.nodeChooseBase(data) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
if (activityDialog != null) {
|
||||||
stopUploadTimer()
|
if(activityDialog!!.isShowing){
|
||||||
mainAtyVM.stopHeartBeat()
|
activityDialog!!.dismiss()
|
||||||
if(dialogDoMainChoose!=null){
|
|
||||||
if(dialogDoMainChoose!!.isShowing){
|
|
||||||
dialogDoMainChoose!!.dismiss()
|
|
||||||
dialogDoMainChoose=null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
super.onDestroy()
|
||||||
|
stopUploadTimer()
|
||||||
|
mainAtyVM.stopHeartBeat()
|
||||||
}
|
}
|
||||||
class PageInfo {
|
|
||||||
var page = 1
|
|
||||||
fun nextPage() {
|
|
||||||
page++
|
|
||||||
}
|
|
||||||
|
|
||||||
fun reset() {
|
|
||||||
page = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
val isFirstPage: Boolean
|
|
||||||
get() = page == 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -14,8 +14,8 @@ import com.yingmao.clash.R
|
||||||
import com.yingmao.clash.base.BaseActivity
|
import com.yingmao.clash.base.BaseActivity
|
||||||
import com.cncat.vpn.common.log.Log
|
import com.cncat.vpn.common.log.Log
|
||||||
import com.yingmao.clash.conf.BZYConstants
|
import com.yingmao.clash.conf.BZYConstants
|
||||||
import com.yingmao.clash.fragment.NewAccFragment
|
|
||||||
import com.cncat.vpn.service.model.AccessControlMode
|
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.RxToast
|
||||||
import com.yingmao.clash.view.popwindow.CommonPopupWindow
|
import com.yingmao.clash.view.popwindow.CommonPopupWindow
|
||||||
import okio.ByteString.Companion.encode
|
import okio.ByteString.Companion.encode
|
||||||
|
|
@ -120,7 +120,7 @@ class ProxyModeActivity : BaseActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
llApplicationMode.setOnClickListener {
|
llApplicationMode.setOnClickListener {
|
||||||
if (NewAccFragment.clashRunning) {
|
if (HomeFragment.clashRunning) {
|
||||||
RxToast.info("请关闭加速后再选择.");
|
RxToast.info("请关闭加速后再选择.");
|
||||||
return@setOnClickListener
|
return@setOnClickListener
|
||||||
}
|
}
|
||||||
|
|
@ -207,7 +207,7 @@ class ProxyModeActivity : BaseActivity() {
|
||||||
|
|
||||||
when (proxyMode) {
|
when (proxyMode) {
|
||||||
ProxyMode.PAC -> {
|
ProxyMode.PAC -> {
|
||||||
NewAccFragment.isGlo = false
|
HomeFragment.isGlo = false
|
||||||
radio_but_global.isChecked = false
|
radio_but_global.isChecked = false
|
||||||
radio_but_pac.isChecked = true
|
radio_but_pac.isChecked = true
|
||||||
radioApplicationMode.isChecked = false
|
radioApplicationMode.isChecked = false
|
||||||
|
|
@ -218,7 +218,7 @@ class ProxyModeActivity : BaseActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ProxyMode.GLOBAL -> {
|
ProxyMode.GLOBAL -> {
|
||||||
NewAccFragment.isGlo = true
|
HomeFragment.isGlo = true
|
||||||
radio_but_global.isChecked = true
|
radio_but_global.isChecked = true
|
||||||
radio_but_pac.isChecked = false
|
radio_but_pac.isChecked = false
|
||||||
radioApplicationMode.isChecked = false
|
radioApplicationMode.isChecked = false
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,9 @@ class SplashHelper(private val splashAtyVM: PublicViewMode) {
|
||||||
third: (AsyncCallback) -> Unit,
|
third: (AsyncCallback) -> Unit,
|
||||||
callback: (Boolean) -> 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) {
|
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) // 所有方法都失败
|
callback(false) // 所有方法都失败
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ import com.yingmao.clash.R
|
||||||
import com.yingmao.clash.app.MainApplication
|
import com.yingmao.clash.app.MainApplication
|
||||||
import com.yingmao.clash.app.MainApplication.Companion.OAID
|
import com.yingmao.clash.app.MainApplication.Companion.OAID
|
||||||
import com.yingmao.clash.base.BaseActivity
|
import com.yingmao.clash.base.BaseActivity
|
||||||
import com.yingmao.clash.captcha.Captcha
|
|
||||||
import com.yingmao.clash.conf.BZYConstants
|
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_IS_REGISTER
|
||||||
import com.yingmao.clash.conf.BZYConstants.Companion.MMKV_KEY_NOTE_DEFAULT_PSW
|
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.RxDialogSureCancel
|
||||||
import com.yingmao.clash.view.dialog.SplashDialog
|
import com.yingmao.clash.view.dialog.SplashDialog
|
||||||
import com.yingmao.clash.vm.SplashAtyVM
|
import com.yingmao.clash.vm.SplashAtyVM
|
||||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
import kotlinx.coroutines.MainScope
|
import kotlinx.coroutines.MainScope
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
|
@ -434,56 +432,7 @@ class SplashActivity : BaseActivity() {
|
||||||
super.onStarted()
|
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<Captcha>(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) {
|
private fun isNeedRegister(isNeedRegister: Boolean) {
|
||||||
if (!BuildConfig.is_free && BuildConfig.productId.isNotEmpty()) { //渠道包都自动注册登录,广州22222也是非自动注册
|
if (!BuildConfig.is_free && BuildConfig.productId.isNotEmpty()) { //渠道包都自动注册登录,广州22222也是非自动注册
|
||||||
|
|
@ -677,6 +626,7 @@ class SplashActivity : BaseActivity() {
|
||||||
val expired = checkLoginRsp.data?.expired
|
val expired = checkLoginRsp.data?.expired
|
||||||
val isPerfect = checkLoginRsp.data?.isPerfect
|
val isPerfect = checkLoginRsp.data?.isPerfect
|
||||||
val userCommand = checkLoginRsp.data?.userCommand
|
val userCommand = checkLoginRsp.data?.userCommand
|
||||||
|
val logSwitch = checkLoginRsp.data?.logSwitch
|
||||||
val mmkv = MMKV.defaultMMKV()
|
val mmkv = MMKV.defaultMMKV()
|
||||||
mmkv.encode(BZYConstants.MMKV_KEY_VPN_EXPIRED, expired ?: true)
|
mmkv.encode(BZYConstants.MMKV_KEY_VPN_EXPIRED, expired ?: true)
|
||||||
mmkv.encode(
|
mmkv.encode(
|
||||||
|
|
@ -685,11 +635,8 @@ class SplashActivity : BaseActivity() {
|
||||||
)
|
)
|
||||||
mmkv.encode(BZYConstants.MMKV_KEY_IS_PERFECT, isPerfect ?: true)
|
mmkv.encode(BZYConstants.MMKV_KEY_IS_PERFECT, isPerfect ?: true)
|
||||||
mmkv.encode(BZYConstants.MMKV_KEY_VPN_UserCommand, userCommand ?: "")
|
mmkv.encode(BZYConstants.MMKV_KEY_VPN_UserCommand, userCommand ?: "")
|
||||||
|
mmkv.encode(BZYConstants.MMKV_KEY_VPN_LogSwitch, logSwitch ?: "")
|
||||||
|
|
||||||
toMainPage()
|
toMainPage()
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
toLoginPage()
|
toLoginPage()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ import com.yingmao.clash.net.http.HttpReqType
|
||||||
import com.yingmao.clash.net.http.HttpStatus
|
import com.yingmao.clash.net.http.HttpStatus
|
||||||
import com.yingmao.clash.net.http.NetService
|
import com.yingmao.clash.net.http.NetService
|
||||||
import com.yingmao.clash.net.http.entity.AppVersionCheckRsp
|
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.GetActivityRsp
|
||||||
import com.yingmao.clash.net.http.entity.PhDownloadUrlRsp
|
import com.yingmao.clash.net.http.entity.PhDownloadUrlRsp
|
||||||
import com.yingmao.clash.net.http.entity.SubscriptionRsp
|
import com.yingmao.clash.net.http.entity.SubscriptionRsp
|
||||||
|
|
@ -83,7 +84,7 @@ import java.util.UUID
|
||||||
class UIMainActivity : BaseActivity() {
|
class UIMainActivity : BaseActivity() {
|
||||||
private lateinit var bottomNavigationView: BottomNavigationView
|
private lateinit var bottomNavigationView: BottomNavigationView
|
||||||
|
|
||||||
private val fragments = arrayListOf<Fragment>()
|
val fragments = arrayListOf<Fragment>()
|
||||||
private lateinit var mainAtyVM: MainAtyVM
|
private lateinit var mainAtyVM: MainAtyVM
|
||||||
private var payResultLoading: RxDialogShapeLoading? = null
|
private var payResultLoading: RxDialogShapeLoading? = null
|
||||||
private val clashRunning: Boolean
|
private val clashRunning: Boolean
|
||||||
|
|
@ -92,19 +93,20 @@ class UIMainActivity : BaseActivity() {
|
||||||
private var timer: Timer? = null
|
private var timer: Timer? = null
|
||||||
private var uTimerTask: TimerTask? = null
|
private var uTimerTask: TimerTask? = null
|
||||||
private var newMainActGlo: Boolean = false
|
private var newMainActGlo: Boolean = false
|
||||||
private var homeFragment:HomeFragment?=null
|
private var homeFragment: HomeFragment? = null
|
||||||
private var settingFragment:SettingFragment?=null
|
private var settingFragment: SettingFragment? = null
|
||||||
|
|
||||||
@SuppressLint("SimpleDateFormat")
|
@SuppressLint("SimpleDateFormat")
|
||||||
private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
|
private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
|
||||||
private var activityDialog: ActivityViewDialog? = null
|
private var activityDialog: ActivityViewDialog? = null
|
||||||
private var checkPayResultDia: MaterialDialog? = null
|
private var checkPayResultDia: MaterialDialog? = null
|
||||||
private var checkBindAccountDia: MaterialDialog? = null
|
private var checkBindAccountDia: MaterialDialog? = null
|
||||||
|
private val mPageInfo = PageInfo()
|
||||||
companion object {
|
companion object {
|
||||||
//记录心跳失败次数
|
//记录心跳失败次数
|
||||||
var HEART_BEAT_FAILURE_FREQUENCY = 0
|
var HEART_BEAT_FAILURE_FREQUENCY = 0
|
||||||
const val REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY = 1000
|
const val REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY = 1000
|
||||||
var isSubbed = false
|
var isSubed = false
|
||||||
var newUuid: String? = null
|
var newUuid: String? = null
|
||||||
var subUrl: String? = null
|
var subUrl: String? = null
|
||||||
var clashBinder: IClashManager? = null
|
var clashBinder: IClashManager? = null
|
||||||
|
|
@ -112,6 +114,71 @@ class UIMainActivity : BaseActivity() {
|
||||||
var isUpload: Boolean = false
|
var isUpload: Boolean = false
|
||||||
var hostsMem: ArrayList<String> = ArrayList()
|
var hostsMem: ArrayList<String> = ArrayList()
|
||||||
var newMainActGlo: Boolean = false
|
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?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
|
@ -130,6 +197,7 @@ class UIMainActivity : BaseActivity() {
|
||||||
newMainActGlo = isGlobal
|
newMainActGlo = isGlobal
|
||||||
startLog()
|
startLog()
|
||||||
firstEntry()
|
firstEntry()
|
||||||
|
mainAtyVM.getExpensesRecord(mPageInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initView(savedInstanceState: Bundle?) {
|
private fun initView(savedInstanceState: Bundle?) {
|
||||||
|
|
@ -147,6 +215,7 @@ class UIMainActivity : BaseActivity() {
|
||||||
if (homeFragment == null) homeFragment = HomeFragment()
|
if (homeFragment == null) homeFragment = HomeFragment()
|
||||||
showFragment(homeFragment!!)
|
showFragment(homeFragment!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.navigation_setting -> {
|
R.id.navigation_setting -> {
|
||||||
if (settingFragment == null) settingFragment = SettingFragment()
|
if (settingFragment == null) settingFragment = SettingFragment()
|
||||||
showFragment(settingFragment!!)
|
showFragment(settingFragment!!)
|
||||||
|
|
@ -162,6 +231,7 @@ class UIMainActivity : BaseActivity() {
|
||||||
transaction.replace(R.id.fragmentContainer, fragment)
|
transaction.replace(R.id.fragmentContainer, fragment)
|
||||||
transaction.commit()
|
transaction.commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showFragment(fragment: Fragment) {
|
private fun showFragment(fragment: Fragment) {
|
||||||
val fragmentManager = supportFragmentManager
|
val fragmentManager = supportFragmentManager
|
||||||
val transaction = fragmentManager.beginTransaction()
|
val transaction = fragmentManager.beginTransaction()
|
||||||
|
|
@ -178,6 +248,7 @@ class UIMainActivity : BaseActivity() {
|
||||||
}
|
}
|
||||||
transaction.commit()
|
transaction.commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun httpLoading(httpStatus: HttpStatus.Loading) {
|
override fun httpLoading(httpStatus: HttpStatus.Loading) {
|
||||||
if (httpStatus.reqType == HttpReqType.HEARTBEAT) {
|
if (httpStatus.reqType == HttpReqType.HEARTBEAT) {
|
||||||
Logger.d("心跳中")
|
Logger.d("心跳中")
|
||||||
|
|
@ -195,6 +266,7 @@ class UIMainActivity : BaseActivity() {
|
||||||
}
|
}
|
||||||
data.data.let { url ->
|
data.data.let { url ->
|
||||||
android.util.Log.e("Data", "机场URL:=${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()) {
|
// if (url.isNotEmpty()) {
|
||||||
// subUrl = url
|
// subUrl = url
|
||||||
// lifecycleScope.launch(Dispatchers.IO) {
|
// lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
|
@ -206,13 +278,13 @@ class UIMainActivity : BaseActivity() {
|
||||||
var pro_sub_url =
|
var pro_sub_url =
|
||||||
MMKV.defaultMMKV().decodeString(BZYConstants.PROFILE_SUB_URL, "")
|
MMKV.defaultMMKV().decodeString(BZYConstants.PROFILE_SUB_URL, "")
|
||||||
// Log.d("pro_sub_url==>${pro_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) {
|
if (pro_sub_url == url) {
|
||||||
subUrl = url
|
subUrl = url
|
||||||
} else {
|
} else {
|
||||||
subUrl = pro_sub_url
|
subUrl = pro_sub_url
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
subUrl = url
|
subUrl = url
|
||||||
}
|
}
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
|
@ -229,7 +301,7 @@ class UIMainActivity : BaseActivity() {
|
||||||
if (data.code == 200) {
|
if (data.code == 200) {
|
||||||
if (data.data.data.list.isNotEmpty()) {
|
if (data.data.data.list.isNotEmpty()) {
|
||||||
data.data.data.list[0].redirectLink.let {
|
data.data.data.list[0].redirectLink.let {
|
||||||
if(activityDialog==null){
|
if (activityDialog == null) {
|
||||||
activityDialog =
|
activityDialog =
|
||||||
ActivityViewDialog(this, data.data.data.list[0].redirectLink)
|
ActivityViewDialog(this, data.data.data.list[0].redirectLink)
|
||||||
activityDialog?.setOnDialogClickListener(object :
|
activityDialog?.setOnDialogClickListener(object :
|
||||||
|
|
@ -262,8 +334,10 @@ class UIMainActivity : BaseActivity() {
|
||||||
val expired = checkLoginRsp.data.expired
|
val expired = checkLoginRsp.data.expired
|
||||||
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)
|
||||||
val hf = supportFragmentManager.findFragmentById(R.id.fragmentContainer) as? HomeFragment
|
val hf =
|
||||||
val sf = supportFragmentManager.findFragmentById(R.id.fragmentContainer) as? SettingFragment
|
supportFragmentManager.findFragmentById(R.id.fragmentContainer) as? HomeFragment
|
||||||
|
val sf =
|
||||||
|
supportFragmentManager.findFragmentById(R.id.fragmentContainer) as? SettingFragment
|
||||||
hf?.setExpireDate()
|
hf?.setExpireDate()
|
||||||
sf?.setExpireDate()
|
sf?.setExpireDate()
|
||||||
checkPayResultDia?.dismiss()
|
checkPayResultDia?.dismiss()
|
||||||
|
|
@ -272,7 +346,10 @@ class UIMainActivity : BaseActivity() {
|
||||||
} else {
|
} else {
|
||||||
// RxToast.info(resources.getString(R.string.PaymentResultsStr))
|
// 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))
|
RxToast.info(resources.getString(R.string.QueryFailed))
|
||||||
}
|
}
|
||||||
payResultLoading?.dismiss()
|
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 -> {
|
else -> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -342,6 +442,7 @@ class UIMainActivity : BaseActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showLoadingDialog(msg: String) {
|
private fun showLoadingDialog(msg: String) {
|
||||||
payResultLoading = RxDialogShapeLoading(this)
|
payResultLoading = RxDialogShapeLoading(this)
|
||||||
payResultLoading!!.setMessage(msg)
|
payResultLoading!!.setMessage(msg)
|
||||||
|
|
@ -355,10 +456,15 @@ class UIMainActivity : BaseActivity() {
|
||||||
MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_SELECTED_NAME_KEY)
|
MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_SELECTED_NAME_KEY)
|
||||||
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_VPN_UserCommand)
|
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_VPN_UserCommand)
|
||||||
MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_All_ITEM_NAME_KEY)
|
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}")
|
Log.d("cleanUserInfo clashRunning==>${clashRunning}")
|
||||||
|
//清除源切换记录
|
||||||
|
|
||||||
if (clashRunning) {
|
if (clashRunning) {
|
||||||
fragments.filterIsInstance<HomeFragment>().forEach { it.stopClash() }
|
fragments.filterIsInstance<HomeFragment>().forEach { it.stopClash() }
|
||||||
}
|
}
|
||||||
|
isSubed=false
|
||||||
stopUploadTimer()
|
stopUploadTimer()
|
||||||
mainAtyVM.stopHeartBeat()
|
mainAtyVM.stopHeartBeat()
|
||||||
cleanProfile()
|
cleanProfile()
|
||||||
|
|
@ -367,6 +473,7 @@ class UIMainActivity : BaseActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startUploadTimer() {
|
fun startUploadTimer() {
|
||||||
|
stopUploadTimer()
|
||||||
if (timer == null) {
|
if (timer == null) {
|
||||||
timer = Timer()
|
timer = Timer()
|
||||||
uTimerTask = object : TimerTask() {
|
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() {
|
private fun startLog() {
|
||||||
|
|
||||||
|
|
@ -558,7 +611,7 @@ class UIMainActivity : BaseActivity() {
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
if (activityDialog != null) {
|
if (activityDialog != null) {
|
||||||
if(activityDialog!!.isShowing){
|
if (activityDialog!!.isShowing) {
|
||||||
activityDialog!!.dismiss()
|
activityDialog!!.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -681,4 +734,38 @@ class UIMainActivity : BaseActivity() {
|
||||||
REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY
|
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<HomeFragment>().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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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<View>(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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -170,7 +170,21 @@ class MainApplication : Application() {
|
||||||
BaiduAction.setActivateInterval(this, 7)
|
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) {
|
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
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@ import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.ActivityInfo
|
import android.content.pm.ActivityInfo
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
|
import android.net.ConnectivityManager
|
||||||
|
import android.net.NetworkCapabilities
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
|
@ -13,13 +16,14 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.collection.arraySetOf
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
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
|
||||||
import com.yingmao.clash.R
|
import com.yingmao.clash.R
|
||||||
import com.yingmao.clash.act.MainActivity
|
|
||||||
import com.yingmao.clash.conf.BZYConstants
|
import com.yingmao.clash.conf.BZYConstants
|
||||||
import com.yingmao.clash.conf.Conf
|
import com.yingmao.clash.conf.Conf
|
||||||
import com.cncat.vpn.core.bridge.ClashException
|
import com.cncat.vpn.core.bridge.ClashException
|
||||||
|
|
@ -55,6 +59,10 @@ open class BaseActivity : AppCompatActivity(), CoroutineScope by MainScope(), Br
|
||||||
var baseLoading: RxDialogShapeLoading? = null
|
var baseLoading: RxDialogShapeLoading? = null
|
||||||
val serStore by lazy { ServiceStore(this) }
|
val serStore by lazy { ServiceStore(this) }
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
// var switchFinshSet: MutableSet<String>? = null
|
||||||
|
}
|
||||||
|
|
||||||
sealed class RequestTunnel {
|
sealed class RequestTunnel {
|
||||||
object ReloadAll : RequestTunnel()
|
object ReloadAll : RequestTunnel()
|
||||||
object ReLaunch : 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 mmkv = MMKV.defaultMMKV()
|
||||||
val routerHost = mmkv.decodeStringSet(BZYConstants.MMKV_KEY_ROUTER_HOST, HashSet())
|
val routerHost = mmkv.decodeStringSet(BZYConstants.MMKV_KEY_ROUTER_HOST, HashSet())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun switchServer(): Boolean {
|
fun switchServer(): Boolean {
|
||||||
var isChange = false
|
var isChange = false
|
||||||
|
|
@ -305,6 +314,16 @@ open class BaseActivity : AppCompatActivity(), CoroutineScope by MainScope(), Br
|
||||||
|
|
||||||
return isChange
|
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
|
@Synchronized
|
||||||
fun switchServer2(): Boolean {
|
fun switchServer2(): Boolean {
|
||||||
var isChange = false
|
var isChange = false
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import com.orhanobut.logger.Logger
|
import com.orhanobut.logger.Logger
|
||||||
import com.yingmao.clash.R
|
import com.yingmao.clash.R
|
||||||
import com.yingmao.clash.act.MainActivity
|
|
||||||
import com.cncat.vpn.common.log.Log
|
import com.cncat.vpn.common.log.Log
|
||||||
//import com.yingmao.clash.design.model.DarkMode
|
//import com.yingmao.clash.design.model.DarkMode
|
||||||
//import com.yingmao.clash.design.store.UiStore
|
//import com.yingmao.clash.design.store.UiStore
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,11 @@ import okhttp3.RequestBody
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
import java.io.File
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import java.io.StringWriter
|
import java.io.StringWriter
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
open class BaseViewMode : ViewModel() {
|
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(
|
viewModelScope.launch(
|
||||||
CoroutineExceptionHandler { _,
|
CoroutineExceptionHandler {
|
||||||
exception ->
|
_,
|
||||||
|
exception,
|
||||||
|
->
|
||||||
Log.e("BaseViewMode_doAsync:${exception.toString()}", exception)
|
Log.e("BaseViewMode_doAsync:${exception.toString()}", exception)
|
||||||
statusData.value =
|
statusData.value =
|
||||||
if (exception.message.isNullOrBlank()) HttpStatus.Failure(
|
if (exception.message.isNullOrBlank()) HttpStatus.Failure(
|
||||||
|
|
@ -93,7 +106,7 @@ open class BaseViewMode : ViewModel() {
|
||||||
Log.i("请求结果:$rsp")
|
Log.i("请求结果:$rsp")
|
||||||
statusData.value = HttpStatus.Success(reqType, rsp)
|
statusData.value = HttpStatus.Success(reqType, rsp)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e( "网络请求异常",e)
|
Log.e("网络请求异常", e)
|
||||||
statusData.value = HttpStatus.Failure(reqType, e.toString())
|
statusData.value = HttpStatus.Failure(reqType, e.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -131,11 +144,13 @@ open class BaseViewMode : ViewModel() {
|
||||||
fun doAsyncDelay(
|
fun doAsyncDelay(
|
||||||
reqType: HttpReqType,
|
reqType: HttpReqType,
|
||||||
delayTimeMillis: Long,
|
delayTimeMillis: Long,
|
||||||
doInAsync: suspend () -> BaseRsp
|
doInAsync: suspend () -> BaseRsp,
|
||||||
) {
|
) {
|
||||||
viewModelScope.launch(
|
viewModelScope.launch(
|
||||||
CoroutineExceptionHandler { _,
|
CoroutineExceptionHandler {
|
||||||
exception ->
|
_,
|
||||||
|
exception,
|
||||||
|
->
|
||||||
Log.e("BaseViewMode_doAsyncDelay:${exception.toString()}", exception)
|
Log.e("BaseViewMode_doAsyncDelay:${exception.toString()}", exception)
|
||||||
statusData.value =
|
statusData.value =
|
||||||
if (exception.message.isNullOrBlank()) HttpStatus.Failure(
|
if (exception.message.isNullOrBlank()) HttpStatus.Failure(
|
||||||
|
|
@ -158,7 +173,7 @@ open class BaseViewMode : ViewModel() {
|
||||||
Log.i("请求结果:$rsp")
|
Log.i("请求结果:$rsp")
|
||||||
statusData.value = HttpStatus.Success(reqType, rsp)
|
statusData.value = HttpStatus.Success(reqType, rsp)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e( "网络请求异常",e)
|
Log.e("网络请求异常", e)
|
||||||
// statusData.value = HttpStatus.Failure(reqType,e.toString())
|
// statusData.value = HttpStatus.Failure(reqType,e.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -166,8 +181,10 @@ open class BaseViewMode : ViewModel() {
|
||||||
|
|
||||||
fun doAsyncStrResult(reqType: HttpReqType, doInAsync: suspend () -> String) {
|
fun doAsyncStrResult(reqType: HttpReqType, doInAsync: suspend () -> String) {
|
||||||
viewModelScope.launch(
|
viewModelScope.launch(
|
||||||
CoroutineExceptionHandler { _,
|
CoroutineExceptionHandler {
|
||||||
exception ->
|
_,
|
||||||
|
exception,
|
||||||
|
->
|
||||||
Log.e("BaseViewMode_doAsyncStrResult:${exception.toString()}", exception)
|
Log.e("BaseViewMode_doAsyncStrResult:${exception.toString()}", exception)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -179,7 +196,7 @@ open class BaseViewMode : ViewModel() {
|
||||||
val rsp = result.await()
|
val rsp = result.await()
|
||||||
Log.i("请求结果:$rsp")
|
Log.i("请求结果:$rsp")
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e( "网络请求异常",e)
|
Log.e("网络请求异常", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -187,11 +204,13 @@ open class BaseViewMode : ViewModel() {
|
||||||
fun doAsyncEncodeStr(
|
fun doAsyncEncodeStr(
|
||||||
reqType: HttpReqType,
|
reqType: HttpReqType,
|
||||||
classOfT: Class<out BaseRsp>,
|
classOfT: Class<out BaseRsp>,
|
||||||
doInAsync: suspend () -> String
|
doInAsync: suspend () -> String,
|
||||||
) {
|
) {
|
||||||
viewModelScope.launch(
|
viewModelScope.launch(
|
||||||
CoroutineExceptionHandler() { _,
|
CoroutineExceptionHandler() {
|
||||||
exception ->
|
_,
|
||||||
|
exception,
|
||||||
|
->
|
||||||
Log.e("BaseViewMode_doAsyncEncodeStr:${exception.toString()}", exception)
|
Log.e("BaseViewMode_doAsyncEncodeStr:${exception.toString()}", exception)
|
||||||
statusData.value =
|
statusData.value =
|
||||||
if (exception.message.isNullOrBlank()) HttpStatus.Failure(
|
if (exception.message.isNullOrBlank()) HttpStatus.Failure(
|
||||||
|
|
@ -221,20 +240,22 @@ open class BaseViewMode : ViewModel() {
|
||||||
statusData.value = HttpStatus.Success(reqType, rsp)
|
statusData.value = HttpStatus.Success(reqType, rsp)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e("网络请求异常",e)
|
Log.e("网络请求异常", e)
|
||||||
throw e
|
throw e
|
||||||
statusData.value = HttpStatus.Failure(reqType,e.toString())
|
statusData.value = HttpStatus.Failure(reqType, e.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun doAsyncEncodeStrBg(
|
suspend fun doAsyncEncodeStrBg(
|
||||||
classOfT: Class<out BaseRsp>,
|
classOfT: Class<out BaseRsp>,
|
||||||
doInAsync: suspend () -> String
|
doInAsync: suspend () -> String,
|
||||||
): BaseRsp? {
|
): BaseRsp? {
|
||||||
return viewModelScope.async(
|
return viewModelScope.async(
|
||||||
CoroutineExceptionHandler() { _,
|
CoroutineExceptionHandler() {
|
||||||
exception ->
|
_,
|
||||||
|
exception,
|
||||||
|
->
|
||||||
Log.e("BaseViewMode_doAsyncEncodeStrBg:${exception.toString()}", exception)
|
Log.e("BaseViewMode_doAsyncEncodeStrBg:${exception.toString()}", exception)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
|
|
@ -247,7 +268,7 @@ open class BaseViewMode : ViewModel() {
|
||||||
val rsp = Gson().fromJson(decodeRspStr, classOfT)
|
val rsp = Gson().fromJson(decodeRspStr, classOfT)
|
||||||
return@async rsp
|
return@async rsp
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e("网络请求异常",e)
|
Log.e("网络请求异常", e)
|
||||||
}
|
}
|
||||||
return@async null
|
return@async null
|
||||||
}.await()
|
}.await()
|
||||||
|
|
@ -262,7 +283,7 @@ open class BaseViewMode : ViewModel() {
|
||||||
}
|
}
|
||||||
result.await()
|
result.await()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e("网络请求异常",e)
|
Log.e("网络请求异常", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ open class PublicViewMode : BaseViewMode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildConfig.is_tz -> {
|
BuildConfig.is_tz -> {
|
||||||
rt.getTzHostGithub()
|
rt.getTzHostTZ()
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildConfig.is_yunti -> {
|
BuildConfig.is_yunti -> {
|
||||||
|
|
@ -38,7 +38,7 @@ open class PublicViewMode : BaseViewMode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
rt.getBzyHostGithub()
|
rt.getBzyHostDef()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
host.takeIf { it.isNotEmpty() }?.let {
|
host.takeIf { it.isNotEmpty() }?.let {
|
||||||
|
|
|
||||||
|
|
@ -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<String, Integer, Bitmap> {
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -28,6 +28,7 @@ class BZYConstants {
|
||||||
const val MMKV_KEY_OLD_CURRENT_HOST = "old_current_host"
|
const val MMKV_KEY_OLD_CURRENT_HOST = "old_current_host"
|
||||||
//备用地址
|
//备用地址
|
||||||
const val MMKV_KEY_ROUTER_HOST ="router_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_FIRST_HOST ="first_host"
|
||||||
const val MMKV_KEY_Airport_Base64 ="airport_base64"
|
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_EXPIRED = "expired"
|
||||||
|
|
||||||
const val MMKV_KEY_VPN_UserCommand = "userCommand"
|
const val MMKV_KEY_VPN_UserCommand = "userCommand"
|
||||||
|
const val MMKV_KEY_VPN_LogSwitch = "logSwitch"
|
||||||
|
|
||||||
//vpn过期时间
|
//vpn过期时间
|
||||||
const val MMKV_KEY_VPN_VALID_PERIOD = "vpn_valid_period"
|
const val MMKV_KEY_VPN_VALID_PERIOD = "vpn_valid_period"
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,9 @@ data class UserData(
|
||||||
@field:SerializedName("userCommand")
|
@field:SerializedName("userCommand")
|
||||||
val userCommand: String? = null,
|
val userCommand: String? = null,
|
||||||
|
|
||||||
|
@field:SerializedName("logSwitch")
|
||||||
|
val logSwitch: String? = null,
|
||||||
|
|
||||||
@field:SerializedName("intervalTime")
|
@field:SerializedName("intervalTime")
|
||||||
val intervalTime: Int? = null,
|
val intervalTime: Int? = null,
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.yingmao.clash.fragment
|
package com.yingmao.clash.fragment
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
|
@ -9,9 +10,14 @@ import android.widget.ImageView
|
||||||
import android.widget.RelativeLayout
|
import android.widget.RelativeLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import com.tencent.mmkv.MMKV
|
||||||
|
import com.yingmao.clash.BuildConfig
|
||||||
import com.yingmao.clash.R
|
import com.yingmao.clash.R
|
||||||
import com.yingmao.clash.base.BaseViewMode
|
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 com.yingmao.clash.net.http.HttpStatus
|
||||||
|
import java.util.HashSet
|
||||||
|
|
||||||
|
|
||||||
abstract class BaseFragment :Fragment() {
|
abstract class BaseFragment :Fragment() {
|
||||||
|
|
@ -58,4 +64,44 @@ abstract class BaseFragment :Fragment() {
|
||||||
open fun httpSuccess(httpStatus: HttpStatus.Success){}
|
open fun httpSuccess(httpStatus: HttpStatus.Success){}
|
||||||
|
|
||||||
open fun httpFailure(httpStatus: HttpStatus.Failure){}
|
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
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -264,7 +264,7 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis
|
||||||
|
|
||||||
val vpnRequest = context?.startClashService()
|
val vpnRequest = context?.startClashService()
|
||||||
try {
|
try {
|
||||||
startUTimer()
|
start_u_timer()
|
||||||
if (vpnRequest != null) {
|
if (vpnRequest != null) {
|
||||||
val result = startActivityForResult(
|
val result = startActivityForResult(
|
||||||
ActivityResultContracts.StartActivityForResult(), vpnRequest
|
ActivityResultContracts.StartActivityForResult(), vpnRequest
|
||||||
|
|
@ -273,17 +273,15 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis
|
||||||
stateChanged(Clash_Starting, true)
|
stateChanged(Clash_Starting, true)
|
||||||
context?.startClashService()
|
context?.startClashService()
|
||||||
accelerateViewModel.appStartupStatus()
|
accelerateViewModel.appStartupStatus()
|
||||||
|
// clashRunning = true
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
accelerateViewModel.appStartupStatus()
|
accelerateViewModel.appStartupStatus()
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
stopUTimer()
|
stop_u_timer()
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
withContext(Dispatchers.Main){
|
|
||||||
hideLoading()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -308,7 +306,7 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis
|
||||||
|
|
||||||
inner class ClashBP : BroadcastReceiver() {
|
inner class ClashBP : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context?, intent: Intent?) {
|
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) {
|
when (intent?.action) {
|
||||||
Intents.ACTION_CLASH_STARTED -> {
|
Intents.ACTION_CLASH_STARTED -> {
|
||||||
if (::rxDialogShapeLoading.isInitialized) {
|
if (::rxDialogShapeLoading.isInitialized) {
|
||||||
|
|
@ -317,6 +315,11 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis
|
||||||
accelerateIv.isSelected = true
|
accelerateIv.isSelected = true
|
||||||
clashRunning = true
|
clashRunning = true
|
||||||
|
|
||||||
|
// MMKV.defaultMMKV().encode(
|
||||||
|
// BZYConstants.MMKV_KEY_CURRENT_NODE,
|
||||||
|
// currentNode
|
||||||
|
// )
|
||||||
|
// setNodeNameAndImg(currentNode!!.name)
|
||||||
if (isAdded) {
|
if (isAdded) {
|
||||||
RxToast.success(resources.getString(R.string.AccelerateSuccess))
|
RxToast.success(resources.getString(R.string.AccelerateSuccess))
|
||||||
}
|
}
|
||||||
|
|
@ -329,11 +332,12 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis
|
||||||
}
|
}
|
||||||
accelerateIv.isSelected = false
|
accelerateIv.isSelected = false
|
||||||
clashRunning = false
|
clashRunning = false
|
||||||
stopUTimer()
|
stop_u_timer()
|
||||||
}
|
}
|
||||||
|
|
||||||
Intents.ACTION_CLASH_REQUEST_STOP -> {
|
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.isInitialized) {
|
||||||
if (!rxDialogShapeLoading.isShowing) {
|
if (!rxDialogShapeLoading.isShowing) {
|
||||||
if (isAdded) {
|
if (isAdded) {
|
||||||
|
|
@ -345,7 +349,7 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis
|
||||||
}
|
}
|
||||||
|
|
||||||
Intents.ACTION_Glo_Mode -> {
|
Intents.ACTION_Glo_Mode -> {
|
||||||
val mode = intent.getBooleanExtra("mode", false)
|
var mode = intent.getBooleanExtra("mode", false)
|
||||||
Log.d("ACTION_Glo_Mode mode==>${mode}")
|
Log.d("ACTION_Glo_Mode mode==>${mode}")
|
||||||
isGlo = 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}")
|
Logger.i("!!!!!!!!!!:${state}")
|
||||||
|
|
||||||
when (state) {
|
when (state) {
|
||||||
|
|
@ -362,11 +373,18 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis
|
||||||
rxDialogShapeLoading.cancel()
|
rxDialogShapeLoading.cancel()
|
||||||
}
|
}
|
||||||
accelerateIv.isSelected = true
|
accelerateIv.isSelected = true
|
||||||
|
// MMKV.defaultMMKV().encode(
|
||||||
|
// BZYConstants.MMKV_KEY_CURRENT_NODE,
|
||||||
|
// currentNode
|
||||||
|
// )
|
||||||
|
// setNodeNameAndImg(currentNode!!.name)
|
||||||
if (isShowToast) {
|
if (isShowToast) {
|
||||||
if (isAdded) {
|
if (isAdded) {
|
||||||
RxToast.success(resources.getString(R.string.AccelerateSuccess))
|
RxToast.success(resources.getString(R.string.AccelerateSuccess))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// File("${Core.deviceStorage.noBackupFilesDir}/${BaseService.CONFIG_FILE}").delete()
|
||||||
|
accelerateViewModel.appStartupStatus()
|
||||||
}
|
}
|
||||||
|
|
||||||
Clash_Stop -> {
|
Clash_Stop -> {
|
||||||
|
|
@ -374,6 +392,9 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis
|
||||||
rxDialogShapeLoading.cancel()
|
rxDialogShapeLoading.cancel()
|
||||||
}
|
}
|
||||||
accelerateIv.isSelected = false
|
accelerateIv.isSelected = false
|
||||||
|
// if (reConnection) {
|
||||||
|
// connectVPNSS(currentNode)
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
Clash_Starting -> {
|
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 -> {}
|
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?) {
|
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 (requestCode == REQUEST_CONNECT) {
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
if (clashRunning) {
|
if (clashRunning) {
|
||||||
Log.d("clashRunning $clashRunning")
|
Log.d("clashRunning $clashRunning")
|
||||||
} else {
|
} else {
|
||||||
startClash(false)
|
startClash()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (::rxDialogShapeLoading.isInitialized || rxDialogShapeLoading.isShowing) {
|
if (::rxDialogShapeLoading.isInitialized || rxDialogShapeLoading.isShowing) {
|
||||||
|
|
@ -425,7 +436,25 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (requestCode == CHECK_NODE_REQUEST_CODE) {
|
} 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) {
|
} else if (requestCode == Proxy_Mode_REQUEST_CODE) {
|
||||||
checkGlo()
|
checkGlo()
|
||||||
}
|
}
|
||||||
|
|
@ -433,7 +462,8 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis
|
||||||
|
|
||||||
@SuppressLint("SimpleDateFormat")
|
@SuppressLint("SimpleDateFormat")
|
||||||
fun setExpireDate() {
|
fun setExpireDate() {
|
||||||
val isExpire = checkExpire()
|
var isExpire = checkExpire()
|
||||||
|
// var isExpire = false
|
||||||
var endTimeInfo = "--"
|
var endTimeInfo = "--"
|
||||||
if (isExpire) {
|
if (isExpire) {
|
||||||
if (isAdded) {
|
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 {
|
private fun checkExpire(): Boolean {
|
||||||
val validPeriod = MMKV.defaultMMKV().decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD)
|
val validPeriod = MMKV.defaultMMKV().decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD)
|
||||||
if (validPeriod > 0) {
|
if (validPeriod > 0) {
|
||||||
val nowTime = System.currentTimeMillis();
|
var nowTime = System.currentTimeMillis();
|
||||||
Log.d("validPeriod==>$validPeriod, nowTime==>$nowTime")
|
com.cncat.vpn.common.log.Log.d("validPeriod==>$validPeriod, nowTime==>$nowTime")
|
||||||
if (validPeriod >= nowTime) {
|
if (validPeriod >= nowTime) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
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() {
|
private fun updateUserInfo() {
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
val mainAct = activity as NewMainActivity
|
var mact = activity as NewMainActivity
|
||||||
mainAct.goCheckLogin()
|
mact.goCheckLogin()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startUTimer() {
|
private fun start_u_timer() {
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
val mainAct = activity as NewMainActivity
|
var mact = activity as NewMainActivity
|
||||||
mainAct.startUploadTimer()
|
mact.startUploadTimer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun stopUTimer() {
|
private fun stop_u_timer() {
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
val mainAct = activity as NewMainActivity
|
var mact = activity as NewMainActivity
|
||||||
mainAct.stopUploadTimer()
|
mact.stopUploadTimer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -529,6 +639,7 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis
|
||||||
val isGlobal = isGlo
|
val isGlobal = isGlo
|
||||||
val isGlobal2 = MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_GLOBAL_MODEL, false)
|
val isGlobal2 = MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_GLOBAL_MODEL, false)
|
||||||
Log.i("checkGlo isGlobal==>${isGlobal}, isGlobal2==>${isGlobal2}")
|
Log.i("checkGlo isGlobal==>${isGlobal}, isGlobal2==>${isGlobal2}")
|
||||||
|
setProxyModeView(isGlobal)
|
||||||
launch(Dispatchers.IO) {
|
launch(Dispatchers.IO) {
|
||||||
if (isGlobal) {
|
if (isGlobal) {
|
||||||
if (clashRunning) {
|
if (clashRunning) {
|
||||||
|
|
@ -537,15 +648,15 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis
|
||||||
} else {
|
} else {
|
||||||
if (clashRunning) {
|
if (clashRunning) {
|
||||||
delay(1000)
|
delay(1000)
|
||||||
clashBinder?.let { cm ->
|
NewMainActivity.clashBinder?.let { cm ->
|
||||||
val names = cm.queryProxyGroupNames(false)
|
val names = cm.queryProxyGroupNames(false)
|
||||||
Log.i("checkGlo names==>${names}")
|
Log.i("checkGlo names==>${names}")
|
||||||
if (names.isNotEmpty()) {
|
if (names.isNotEmpty()) {
|
||||||
val selectedName =
|
var selected_name =
|
||||||
MMKV.defaultMMKV()
|
MMKV.defaultMMKV()
|
||||||
.decodeString(BZYConstants.NODE_SELECTED_NAME_KEY, "");
|
.decodeString(BZYConstants.NODE_SELECTED_NAME_KEY, "");
|
||||||
Log.i("selected_name ==>${selectedName}")
|
Log.i("selected_name ==>${selected_name}")
|
||||||
if (!TextUtils.isEmpty(selectedName)) {
|
if (!TextUtils.isEmpty(selected_name)) {
|
||||||
val o = cm.queryOverride(Clash.OverrideSlot.Session)
|
val o = cm.queryOverride(Clash.OverrideSlot.Session)
|
||||||
o.mode = TunnelState.Mode.Rule
|
o.mode = TunnelState.Mode.Rule
|
||||||
cm.patchOverride(Clash.OverrideSlot.Session, o)
|
cm.patchOverride(Clash.OverrideSlot.Session, o)
|
||||||
|
|
@ -558,7 +669,9 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis
|
||||||
gName = names[1]
|
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<ClashNodebBean>
|
|
||||||
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)
|
private fun setProxyModeView(isGlobal: Boolean) {
|
||||||
o.mode = TunnelState.Mode.Global
|
if (isGlobal) {
|
||||||
cm.patchOverride(Clash.OverrideSlot.Session, o)
|
iv_proxy_mode.setImageResource(R.drawable.ic_s_global)
|
||||||
delay(3000)
|
if (isAdded) {
|
||||||
//等待全局模式生效
|
tv_proxy_model.text = resources.getString(R.string.GlobalMode)
|
||||||
var maxIndex = 0
|
}
|
||||||
while (true) {
|
} else {
|
||||||
if (maxIndex > 3) {
|
iv_proxy_mode.setImageResource(R.drawable.smart)
|
||||||
|
if (isAdded) {
|
||||||
|
tv_proxy_model.text = resources.getString(R.string.IntelligentMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var proList: MutableList<ClashNodebBean>? = 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<ClashNodebBean>
|
||||||
|
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
|
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)
|
|
||||||
}
|
}
|
||||||
|
Log.d("repeat agent")
|
||||||
cm.patchSelector("GLOBAL", nodeName)
|
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!=null){
|
||||||
if(dataInfo.data.id!=null){
|
if(dataInfo.data.id!=null){
|
||||||
connectId= dataInfo.data.id
|
connectId= dataInfo.data.id
|
||||||
|
|
||||||
val serviceIntent= Intent(requireContext(), ConnectionService::class.java)
|
val serviceIntent= Intent(requireContext(), ConnectionService::class.java)
|
||||||
serviceIntent.putExtra("receiver",resultReceiver)
|
serviceIntent.putExtra("receiver",resultReceiver)
|
||||||
val serviceRunning =
|
requireContext().startService(serviceIntent)
|
||||||
Utils.isServiceRunning(requireContext(), ConnectionService::class.java)
|
|
||||||
android.util.Log.i("AppStartupStatus","data::"+serviceRunning)
|
|
||||||
if(!serviceRunning){
|
|
||||||
requireContext().startService(serviceIntent)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -689,26 +812,6 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis
|
||||||
val serviceIntent= Intent(requireContext(), ConnectionService::class.java)
|
val serviceIntent= Intent(requireContext(), ConnectionService::class.java)
|
||||||
requireContext().stopService(serviceIntent)
|
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->{
|
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -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<Fragment>) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 当前选中的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 <FrameLayout android:id="@+id/containerViewId"></FrameLayout>
|
|
||||||
*/
|
|
||||||
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 <FrameLayout android:id="@+id/containerViewId"></FrameLayout>
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
android:layout_below="@id/id_fragment_title"
|
|
||||||
android:id="@+id/id_fragment_content"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent" />*/
|
|
||||||
//==============================================================================================Fragment的静态使用 end
|
|
||||||
//----------------------------------------------------------------------------------------------Fragment的动态使用 start
|
|
||||||
/**
|
|
||||||
* androidX 包下的使用
|
|
||||||
* 动态的使用Fragment
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* 在布局文件中使用 FrameLayout 标签
|
|
||||||
*
|
|
||||||
* @param fragment fragment
|
|
||||||
* @param containerViewId <FrameLayout android:id="@+id/containerViewId"></FrameLayout>
|
|
||||||
*/
|
|
||||||
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 <FrameLayout android:id="@+id/containerViewId"></FrameLayout>
|
|
||||||
*/
|
|
||||||
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 <FrameLayout android:id="@+id/containerViewId"></FrameLayout>
|
|
||||||
*/
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,7 +2,6 @@ package com.yingmao.clash.fragment.home
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.ActivityManager
|
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
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.LoginActivity
|
||||||
import com.yingmao.clash.act.UIMainActivity
|
import com.yingmao.clash.act.UIMainActivity
|
||||||
import com.yingmao.clash.act.UIMainActivity.Companion.clashBinder
|
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.newMainActGlo
|
||||||
import com.yingmao.clash.act.UIMainActivity.Companion.newUuid
|
import com.yingmao.clash.act.UIMainActivity.Companion.newUuid
|
||||||
import com.yingmao.clash.act.UIMainActivity.Companion.profileBinder
|
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.BZYConstants
|
||||||
import com.yingmao.clash.conf.Conf
|
import com.yingmao.clash.conf.Conf
|
||||||
import com.yingmao.clash.entity.ClashNodebBean
|
import com.yingmao.clash.entity.ClashNodebBean
|
||||||
import com.yingmao.clash.fragment.AccelerateViewModel
|
|
||||||
import com.yingmao.clash.fragment.BaseFragment
|
import com.yingmao.clash.fragment.BaseFragment
|
||||||
import com.yingmao.clash.listener.AsyncCallBackListener
|
import com.yingmao.clash.listener.AsyncCallBackListener
|
||||||
import com.yingmao.clash.net.http.HttpReqType
|
import com.yingmao.clash.net.http.HttpReqType
|
||||||
import com.yingmao.clash.net.http.HttpStatus
|
import com.yingmao.clash.net.http.HttpStatus
|
||||||
import com.yingmao.clash.net.http.entity.AppStartupStatus
|
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.net.http.entity.PhDownloadUrlRsp
|
||||||
import com.yingmao.clash.service.ConnectionService
|
import com.yingmao.clash.service.ConnectionService
|
||||||
import com.yingmao.clash.util.ActivityResultLifecycle
|
import com.yingmao.clash.util.ActivityResultLifecycle
|
||||||
import com.yingmao.clash.util.CommonUtils
|
import com.yingmao.clash.util.CommonUtils
|
||||||
import com.yingmao.clash.util.MarqueeTextView
|
import com.yingmao.clash.util.MarqueeTextView
|
||||||
import com.yingmao.clash.util.PayUtils
|
import com.yingmao.clash.util.PayUtils
|
||||||
|
import com.yingmao.clash.util.Utils
|
||||||
import com.yingmao.clash.util.startClashService
|
import com.yingmao.clash.util.startClashService
|
||||||
import com.yingmao.clash.util.stopClashService
|
import com.yingmao.clash.util.stopClashService
|
||||||
import com.yingmao.clash.view.RxToast
|
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 llLine: ConstraintLayout
|
||||||
private lateinit var clActivity: ConstraintLayout
|
private lateinit var clActivity: ConstraintLayout
|
||||||
private lateinit var clMember: ConstraintLayout
|
private lateinit var clMember: ConstraintLayout
|
||||||
|
|
||||||
private val fragments = arrayListOf<Fragment>()
|
private val fragments = arrayListOf<Fragment>()
|
||||||
var proList: MutableList<ClashNodebBean>? = null
|
var proList: MutableList<ClashNodebBean>? = null
|
||||||
private val nextRequestKey = AtomicInteger(0)
|
private val nextRequestKey = AtomicInteger(0)
|
||||||
private var reConnection = false
|
private var reConnection = false
|
||||||
private var connectId = -1
|
private var connectId = -1
|
||||||
|
private var baseLoading: RxDialogShapeLoading? = null
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val REQUEST_CONNECT = 1
|
const val REQUEST_CONNECT = 1
|
||||||
|
|
@ -186,8 +183,8 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher
|
||||||
llLine = view.findViewById(R.id.llLine)
|
llLine = view.findViewById(R.id.llLine)
|
||||||
clActivity = view.findViewById(R.id.clActivity)
|
clActivity = view.findViewById(R.id.clActivity)
|
||||||
clMember = view.findViewById(R.id.clMember)
|
clMember = view.findViewById(R.id.clMember)
|
||||||
if (BuildConfig.productId=="182269"&&BuildConfig.is_tz){
|
if (BuildConfig.productId == "182269" && BuildConfig.is_tz) {
|
||||||
clActivity.visibility=View.INVISIBLE
|
clActivity.visibility = View.INVISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
llLine.setOnClickListener {
|
llLine.setOnClickListener {
|
||||||
|
|
@ -212,7 +209,7 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher
|
||||||
return@setOnClickListener
|
return@setOnClickListener
|
||||||
}
|
}
|
||||||
var intent: Intent? = null
|
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)
|
intent = Intent(CommonUtils.getApp(), ChangeNodeTzActivity::class.java)
|
||||||
} else {
|
} else {
|
||||||
intent = Intent(CommonUtils.getApp(), ChangeNodeActivity::class.java)
|
intent = Intent(CommonUtils.getApp(), ChangeNodeActivity::class.java)
|
||||||
|
|
@ -260,7 +257,28 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher
|
||||||
}
|
}
|
||||||
rxDialogSureCancel.show()
|
rxDialogSureCancel.show()
|
||||||
} else {
|
} 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<TextView>(R.id.tv_pay_finish).setOnClickListener {
|
||||||
|
goNewRecharge()
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return@setOnClickListener
|
||||||
|
}
|
||||||
|
showLoading(resources.getString(R.string.Starting), requireContext())
|
||||||
|
startClash(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clActivity.setOnClickListener {
|
clActivity.setOnClickListener {
|
||||||
|
|
@ -276,14 +294,31 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher
|
||||||
|
|
||||||
|
|
||||||
var selected_name =
|
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 (!TextUtils.isEmpty(selected_name)) {
|
||||||
if (!BuildConfig.is_tz){
|
if (!BuildConfig.is_tz) {
|
||||||
setNodeNameAndImg(selected_name!!)
|
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() {
|
private fun updateUserInfo() {
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
val mact = activity as UIMainActivity
|
val mact = activity as UIMainActivity
|
||||||
|
|
@ -384,7 +419,12 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher
|
||||||
MMKV.defaultMMKV().encode(BZYConstants.CONNECTID, dataInfo.data.id)
|
MMKV.defaultMMKV().encode(BZYConstants.CONNECTID, dataInfo.data.id)
|
||||||
val serviceIntent = Intent(requireContext(), ConnectionService::class.java)
|
val serviceIntent = Intent(requireContext(), ConnectionService::class.java)
|
||||||
serviceIntent.putExtra("receiver", resultReceiver)
|
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) {
|
if (clashRunning) {
|
||||||
Log.d("clashRunning $clashRunning")
|
Log.d("clashRunning $clashRunning")
|
||||||
} else {
|
} else {
|
||||||
startClash()
|
startClash(false)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (::rxDialogShapeLoading.isInitialized || rxDialogShapeLoading.isShowing) {
|
if (::rxDialogShapeLoading.isInitialized || rxDialogShapeLoading.isShowing) {
|
||||||
|
|
@ -473,12 +513,12 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher
|
||||||
if (clashRunning) {
|
if (clashRunning) {
|
||||||
Log.d("clashRunning $clashRunning")
|
Log.d("clashRunning $clashRunning")
|
||||||
} else {
|
} else {
|
||||||
startClash()
|
startClash(false)
|
||||||
}
|
}
|
||||||
checkGlo()
|
checkGlo()
|
||||||
}?.run {
|
}?.run {
|
||||||
if (isRunNing == true && !clashRunning) {
|
if (isRunNing == true && !clashRunning) {
|
||||||
startClash()
|
startClash(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (requestCode == Proxy_Mode_REQUEST_CODE) {
|
} else if (requestCode == Proxy_Mode_REQUEST_CODE) {
|
||||||
|
|
@ -486,27 +526,11 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startClash() {
|
private fun startClash(isStart:Boolean) {
|
||||||
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<TextView>(R.id.tv_pay_finish).setOnClickListener {
|
|
||||||
goNewRecharge()
|
|
||||||
dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
launch {
|
launch {
|
||||||
|
if(isStart){
|
||||||
|
delay(2000)
|
||||||
|
}
|
||||||
profileBinder?.let { pm ->
|
profileBinder?.let { pm ->
|
||||||
val active = pm.queryActive()
|
val active = pm.queryActive()
|
||||||
if (active == null) {
|
if (active == null) {
|
||||||
|
|
@ -520,14 +544,12 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher
|
||||||
pm.setActive(profile)
|
pm.setActive(profile)
|
||||||
|
|
||||||
newUuid = profile.uuid.toString()
|
newUuid = profile.uuid.toString()
|
||||||
isSubbed = true
|
|
||||||
} ?: run {
|
} ?: run {
|
||||||
//为空的情况下选择第一个
|
//为空的情况下选择第一个
|
||||||
pm.queryAll().forEach { profile ->
|
pm.queryAll().forEach { profile ->
|
||||||
pm.setActive(profile)
|
pm.setActive(profile)
|
||||||
|
|
||||||
newUuid = profile.uuid.toString()
|
newUuid = profile.uuid.toString()
|
||||||
isSubbed = true
|
|
||||||
return@forEach
|
return@forEach
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -555,6 +577,9 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher
|
||||||
stopUpLoadTimer()
|
stopUpLoadTimer()
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
hideLoading()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -994,4 +1019,14 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher
|
||||||
})
|
})
|
||||||
dialog.show()
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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<View>(R.id.rl_kefu).setOnClickListener(this)
|
|
||||||
it.findViewById<View>(R.id.rl_add_freiend).setOnClickListener(this)
|
|
||||||
rl_band_phone = it.findViewById(R.id.rl_band_phone)
|
|
||||||
|
|
||||||
it.findViewById<View>(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 = "--"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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) }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,8 +1,6 @@
|
||||||
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
|
||||||
|
|
@ -11,8 +9,6 @@ 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
|
||||||
|
|
@ -43,14 +39,12 @@ 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
|
||||||
import com.yingmao.clash.R
|
import com.yingmao.clash.R
|
||||||
import com.yingmao.clash.act.AgreementAndPrivacyActivity
|
import com.yingmao.clash.act.AgreementAndPrivacyActivity
|
||||||
import com.yingmao.clash.act.ChangePwdActivity
|
import com.yingmao.clash.act.ChangePwdActivity
|
||||||
import com.yingmao.clash.act.InstallApplicationActivity
|
|
||||||
import com.yingmao.clash.act.LoginActivity
|
import com.yingmao.clash.act.LoginActivity
|
||||||
import com.yingmao.clash.act.LossPreventionActivity
|
import com.yingmao.clash.act.LossPreventionActivity
|
||||||
import com.yingmao.clash.act.NewMainActivity
|
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.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
|
||||||
|
|
@ -97,7 +90,6 @@ 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) {
|
||||||
|
|
@ -257,10 +249,10 @@ class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatc
|
||||||
}
|
}
|
||||||
setExpireDate()
|
setExpireDate()
|
||||||
|
|
||||||
if (checkExpire()) {
|
if (isVip) {
|
||||||
userIdentity.text = requireActivity().resources.getString(R.string.TemporaryUser)
|
|
||||||
} else {
|
|
||||||
userIdentity.text = requireActivity().resources.getString(R.string.VIPMember)
|
userIdentity.text = requireActivity().resources.getString(R.string.VIPMember)
|
||||||
|
} else {
|
||||||
|
userIdentity.text = requireActivity().resources.getString(R.string.TemporaryUser)
|
||||||
}
|
}
|
||||||
userIdentityNumber.text =
|
userIdentityNumber.text =
|
||||||
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
|
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
|
||||||
|
|
@ -328,7 +320,16 @@ class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatc
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
initializationRepair.setOnClickListener {
|
initializationRepair.setOnClickListener {
|
||||||
|
if (checkExpire()) {
|
||||||
|
RxToast.info(resources.getString(R.string.AccountExpired))
|
||||||
|
return@setOnClickListener
|
||||||
|
}
|
||||||
|
if(clashRunning){
|
||||||
|
RxToast.info("请关闭加速后在进行初始化操作")
|
||||||
|
return@setOnClickListener
|
||||||
|
}
|
||||||
if (TextUtils.isEmpty(subUrl)) {
|
if (TextUtils.isEmpty(subUrl)) {
|
||||||
|
RxToast.success(resources.getString(R.string.tooFast))
|
||||||
return@setOnClickListener
|
return@setOnClickListener
|
||||||
}
|
}
|
||||||
cleanNodeMmkv()
|
cleanNodeMmkv()
|
||||||
|
|
@ -337,6 +338,7 @@ class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatc
|
||||||
launch(Dispatchers.IO) {
|
launch(Dispatchers.IO) {
|
||||||
profileBinder?.let { pm ->
|
profileBinder?.let { pm ->
|
||||||
pm.queryAll().forEach { profile ->
|
pm.queryAll().forEach { profile ->
|
||||||
|
|
||||||
Log.d("setting profile delete ==>${profile.name}")
|
Log.d("setting profile delete ==>${profile.name}")
|
||||||
pm.delete(profile.uuid)
|
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.MMKV_KEY_VPN_UserCommand)
|
||||||
MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_All_ITEM_NAME_KEY)
|
MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_All_ITEM_NAME_KEY)
|
||||||
MMKV.defaultMMKV().removeValueForKey(BZYConstants.PROFILE_SUB_URL)
|
MMKV.defaultMMKV().removeValueForKey(BZYConstants.PROFILE_SUB_URL)
|
||||||
|
|
||||||
|
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_Switch_Finsh_Set)
|
||||||
|
|
||||||
|
//清除源切换记录
|
||||||
|
|
||||||
|
UIMainActivity.isSubed=false
|
||||||
Log.d("cleanUserInfo clashRunning==>${clashRunning}")
|
Log.d("cleanUserInfo clashRunning==>${clashRunning}")
|
||||||
if (clashRunning) {
|
if (clashRunning) {
|
||||||
fragments.filterIsInstance<HomeFragment>().forEach { it.stopClash() }
|
fragments.filterIsInstance<HomeFragment>().forEach { it.stopClash() }
|
||||||
|
|
|
||||||
|
|
@ -228,8 +228,10 @@ interface HttpApi {
|
||||||
|
|
||||||
@GET("/taiziregister.txt")
|
@GET("/taiziregister.txt")
|
||||||
suspend fun getTzRegister(): String
|
suspend fun getTzRegister(): String
|
||||||
|
|
||||||
@GET("/taiziregister_182269.txt")
|
@GET("/taiziregister_182269.txt")
|
||||||
suspend fun getTz182269Register(): String
|
suspend fun getTz182269Register(): String
|
||||||
|
|
||||||
@GET("/bzyregister.txt")
|
@GET("/bzyregister.txt")
|
||||||
suspend fun getBzyRegister(): String
|
suspend fun getBzyRegister(): String
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import okhttp3.Callback
|
||||||
import okhttp3.Cookie
|
import okhttp3.Cookie
|
||||||
import okhttp3.CookieJar
|
import okhttp3.CookieJar
|
||||||
import okhttp3.HttpUrl
|
import okhttp3.HttpUrl
|
||||||
|
import okhttp3.Interceptor
|
||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
|
|
@ -72,6 +73,37 @@ class NetService private constructor() : INetService {
|
||||||
var httpClient: OkHttpClient? = null;
|
var httpClient: OkHttpClient? = null;
|
||||||
var downHttpClient: 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 {
|
override fun httpsClient(connTO:Long,readTO:Long,writeTO:Long): OkHttpClient {
|
||||||
|
|
||||||
var loggingInterceptor = HttpLoggingInterceptor(
|
var loggingInterceptor = HttpLoggingInterceptor(
|
||||||
|
|
@ -79,8 +111,10 @@ class NetService private constructor() : INetService {
|
||||||
override fun log(message: String) {
|
override fun log(message: String) {
|
||||||
Log.d("loggingInterceptor==>$message")
|
Log.d("loggingInterceptor==>$message")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
|
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
|
||||||
var builder = OkHttpClient.Builder()
|
var builder = OkHttpClient.Builder()
|
||||||
.retryOnConnectionFailure(true)
|
.retryOnConnectionFailure(true)
|
||||||
|
|
@ -95,6 +129,7 @@ class NetService private constructor() : INetService {
|
||||||
.hostnameVerifier(getHostnameVerifier()!!)
|
.hostnameVerifier(getHostnameVerifier()!!)
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
builder.addInterceptor(loggingInterceptor)
|
builder.addInterceptor(loggingInterceptor)
|
||||||
|
// builder.addInterceptor(ExceptionLoggingInterceptor())
|
||||||
}
|
}
|
||||||
// builder.addInterceptor(loggingInterceptor)
|
// builder.addInterceptor(loggingInterceptor)
|
||||||
return builder.build()
|
return builder.build()
|
||||||
|
|
@ -161,6 +196,7 @@ class NetService private constructor() : INetService {
|
||||||
.addConverterFactory(ScalarsConverterFactory.create())//json解析器Gson
|
.addConverterFactory(ScalarsConverterFactory.create())//json解析器Gson
|
||||||
.baseUrl(baseUrl) //设置BaseURL需以'/'结尾
|
.baseUrl(baseUrl) //设置BaseURL需以'/'结尾
|
||||||
.build() //创建Retrofit对象
|
.build() //创建Retrofit对象
|
||||||
|
|
||||||
return retrofit.create(HttpApi::class.java)
|
return retrofit.create(HttpApi::class.java)
|
||||||
}
|
}
|
||||||
fun createFreeBaseUrl2(): HttpApi {
|
fun createFreeBaseUrl2(): HttpApi {
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import com.yingmao.clash.fragment.AccelerateViewModel;
|
||||||
public class ConnectionService extends Service {
|
public class ConnectionService extends Service {
|
||||||
|
|
||||||
private static final String TAG = "TimerService";
|
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 Handler handler = new Handler();
|
||||||
private Intent intent;
|
private Intent intent;
|
||||||
private Runnable runnable = new Runnable() {
|
private Runnable runnable = new Runnable() {
|
||||||
|
|
|
||||||
|
|
@ -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<String>();
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -107,7 +107,6 @@ open class DialogDoMainChoose : RxDialog {
|
||||||
}
|
}
|
||||||
domainListAdapter.notifyDataSetChanged()
|
domainListAdapter.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setOnTryButtonListener(listener: OnTryButtonListener) {
|
fun setOnTryButtonListener(listener: OnTryButtonListener) {
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,12 @@ import com.yingmao.clash.act.NewMainActivity
|
||||||
import com.yingmao.clash.base.PublicViewMode
|
import com.yingmao.clash.base.PublicViewMode
|
||||||
import com.cncat.vpn.common.log.Log
|
import com.cncat.vpn.common.log.Log
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.yingmao.clash.act.PageInfo
|
|
||||||
import com.yingmao.clash.app.MainApplication
|
import com.yingmao.clash.app.MainApplication
|
||||||
import com.yingmao.clash.conf.BZYConstants
|
import com.yingmao.clash.conf.BZYConstants
|
||||||
import com.yingmao.clash.entity.CheckLoginRsp
|
import com.yingmao.clash.entity.CheckLoginRsp
|
||||||
import com.yingmao.clash.entity.ClashNodebBean
|
import com.yingmao.clash.entity.ClashNodebBean
|
||||||
import com.yingmao.clash.entity.Node
|
import com.yingmao.clash.entity.Node
|
||||||
|
import com.yingmao.clash.fragment.setting.SettingFragment
|
||||||
import com.yingmao.clash.http.OkHttpBase
|
import com.yingmao.clash.http.OkHttpBase
|
||||||
import com.yingmao.clash.listener.AsyncCallBackListener
|
import com.yingmao.clash.listener.AsyncCallBackListener
|
||||||
import com.yingmao.clash.listener.DownLoadListener
|
import com.yingmao.clash.listener.DownLoadListener
|
||||||
|
|
|
||||||
|
|
@ -401,4 +401,5 @@ Service Description\n
|
||||||
<string name="LoginOut">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.</string>
|
<string name="LoginOut">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.</string>
|
||||||
<string name="tooFast">The application is initializing. Please wait for 1~2 seconds and try again.</string>
|
<string name="tooFast">The application is initializing. Please wait for 1~2 seconds and try again.</string>
|
||||||
<string name="Starting">Starting</string>
|
<string name="Starting">Starting</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -412,8 +412,8 @@
|
||||||
<string name="Switching">切换中,请稍后</string>
|
<string name="Switching">切换中,请稍后</string>
|
||||||
<string name="switchManually">当前节点拥堵请手动切换</string>
|
<string name="switchManually">当前节点拥堵请手动切换</string>
|
||||||
<string name="SwitchingSource">请关闭加速后在进行源切换</string>
|
<string name="SwitchingSource">请关闭加速后在进行源切换</string>
|
||||||
|
|
||||||
<string name="LoginOut">检测到当前账号在其他设备登录,如非本人操作,请立即修改密码并退出陌生设备。</string>
|
<string name="LoginOut">检测到当前账号在其他设备登录,如非本人操作,请立即修改密码并退出陌生设备。</string>
|
||||||
<string name="tooFast">应用初始化中,请等待1~2秒后重试</string>
|
<string name="tooFast">应用初始化中,请等待1~2秒后重试</string>
|
||||||
<string name="Starting">启动中</string>
|
<string name="Starting">启动中</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
Loading…
Reference in New Issue