zhoulian/app/src/main/java/com/yingmao/clash/act/NewMainActivity.kt

1061 lines
43 KiB
Kotlin
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.yingmao.clash.act
import android.Manifest
import android.annotation.SuppressLint
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import android.view.View
import android.view.WindowManager
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.ProgressBar
import android.widget.TextView
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission
import androidx.appcompat.widget.AppCompatImageView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.viewpager2.widget.ViewPager2
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.customview.customView
import com.afollestad.materialdialogs.customview.getCustomView
import com.airbnb.lottie.LottieAnimationView
import com.cncat.vpn.common.log.Log
import com.cncat.vpn.core.model.LogMessage
import com.cncat.vpn.service.ClashManager
import com.cncat.vpn.service.ProfileManager
import com.cncat.vpn.service.model.Profile
import com.cncat.vpn.service.remote.IClashManager
import com.cncat.vpn.service.remote.ILogObserver
import com.cncat.vpn.service.remote.IProfileManager
import com.cncat.vpn.service.remote.wrap
import com.google.gson.Gson
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import com.orhanobut.logger.Logger
import com.tencent.mmkv.MMKV
import com.yingmao.clash.BuildConfig
import com.yingmao.clash.R
import com.yingmao.clash.app.MainApplication
import com.yingmao.clash.base.BaseActivity
import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.conf.BZYConstants.Companion.ScreenFlag
import com.yingmao.clash.conf.Conf
import com.yingmao.clash.entity.CheckLoginRsp
import com.yingmao.clash.fragment.NewAccFragment
import com.yingmao.clash.fragment.NewAccFragment.Companion.CHECK_NODE_REQUEST_CODE
import com.yingmao.clash.listener.DownLoadListener
import com.yingmao.clash.net.http.HttpApi
import com.yingmao.clash.net.http.HttpReqType
import com.yingmao.clash.net.http.HttpStatus
import com.yingmao.clash.net.http.NetService
import com.yingmao.clash.net.http.entity.ExpensesRecordRsp
import com.yingmao.clash.net.http.entity.GetActivityRsp
import com.yingmao.clash.net.http.entity.HeartBeatRsp
import com.yingmao.clash.net.http.entity.PhDownloadUrlRsp
import com.yingmao.clash.net.http.entity.ShowNode
import com.yingmao.clash.net.http.entity.SubscriptionRsp
import com.yingmao.clash.net.http.entity.VipSignRsp
import com.yingmao.clash.remote.Remote
import com.yingmao.clash.util.AESUtil
import com.yingmao.clash.util.CommonUtils
import com.yingmao.clash.util.Utils
import com.yingmao.clash.util.stopClashService
import com.yingmao.clash.view.RxToast
import com.yingmao.clash.view.adapter.MainVPAdapter
import com.yingmao.clash.view.dialog.ActivityViewDialog
import com.yingmao.clash.view.dialog.ActivityViewDialog.OnDialogClickListener
import com.yingmao.clash.view.dialog.DialogAppVersion
import com.yingmao.clash.view.dialog.DialogBandChoose
import com.yingmao.clash.view.dialog.DialogNotice
import com.yingmao.clash.view.dialog.RxDialogShapeLoading
import com.yingmao.clash.vm.MainAtyVM
import com.yingmao.clash.webview.BZYWebViewKeFu
import com.yingmao.clash.webview.BZYWebViewNormal
import com.yingmao.clash.webview.CustomerServiceWebView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody
import java.io.File
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.Timer
import java.util.TimerTask
import java.util.UUID
class NewMainActivity : BaseActivity() {
public val fragments = arrayListOf<Fragment>()
private lateinit var iv_slider: ImageView
private lateinit var ll_slider: ConstraintLayout
lateinit var containerVP: ViewPager2
val clashRunning: Boolean
get() = Remote.broadcasts.clashRunning
// lateinit var tv_rechar: Button
lateinit var tv_username: TextView
lateinit var tv_expire_date: TextView
private lateinit var drawer: DrawerLayout
private lateinit var mainAtyVM: MainAtyVM
private var activityDialog: ActivityViewDialog? = null
private var timer: Timer? = null
private var u_timerTask: TimerTask? = null
private lateinit var ivTor: AppCompatImageView
private lateinit var tvNetStr:TextView
private lateinit var tvTemporaryAccount:TextView
private val mPageInfo = PageInfo()
private var payResultLoading: RxDialogShapeLoading? = null
private var timerJob: Job? = null
private var loadingTimeoutNum = 3
@SuppressLint("SimpleDateFormat")
private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
private lateinit var clExit:ConstraintLayout
companion object {
//记录心跳失败次数
var HEART_BEAT_FAILURE_FREQUENCY = 0
const val REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY = 1000
var newUuid: String? = null
var subUrl: String? = null
var clashBinder: IClashManager? = null
var profileBinder: IProfileManager? = null
var newMainActGlo: Boolean = false
var isUpload: Boolean = false
var hostsMem: ArrayList<String> = ArrayList()
suspend fun setSub2(url: String) {
profileBinder?.let { pm ->
pm.queryAll().forEach { itemPro ->
if (itemPro.name != Conf.getClashConfName(MainApplication.getApp()?.applicationContext)) {
pm.delete(itemPro.uuid)
}
}
val pro = pm.queryAll().find {
it.name == Conf.getClashConfName(MainApplication.getApp()?.applicationContext)
}
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()
} ?: run {
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()
}
}
}
}
}
fun addOrSendHost(host: String) {
Log.d("hostsMem size==>${hostsMem.size}")
if (!hostsMem.contains(host) && !isApiHost(host)) {
hostsMem.add(host + "{" + dateFormat.format(Date()))
}
}
fun isApiHost(host: String): Boolean {
val mmkv = MMKV.defaultMMKV()
var isApiHost = false;
val originalUrl =
mmkv.decodeString(BZYConstants.MMKV_KEY_CURRENT_HOST, BuildConfig.service_url)
val routerHost = mmkv.decodeStringSet(BZYConstants.MMKV_KEY_ROUTER_HOST, HashSet())
// Log.d("originalUrl==>${originalUrl}, host==>${host}")
if (originalUrl?.contains(host) == true) {
isApiHost = true
return isApiHost
}
// Log.d("isApiHost==>${isApiHost}")
routerHost?.forEach { rh ->
isApiHost = rh.contains(host)
// Log.d("rh==>${rh}, host==>${host}, isApiHost==>${isApiHost}")
}
return isApiHost
}
fun uploadLogHttp() {
// Log.d("uploadLogHttp isUpload==>${isUpload}, memSize==>${hostsMem.size}")
if (hostsMem.size <= 0) {
return
}
if (isUpload) {
return
}
isUpload = true
GlobalScope.async {
try {
val hostsJsonArray = JsonArray()
for (hostItem in hostsMem) {
val hostAndTime = hostItem.split("{")
val hostJsonObject = JsonObject()
hostJsonObject.addProperty(
"id", MMKV.defaultMMKV().decodeInt(BZYConstants.MMKV_KEY_NOTE_NODE_ID, 0)
)
hostJsonObject.addProperty("requestHosts", hostAndTime[0])
hostJsonObject.addProperty("requestTime", hostAndTime[1])
hostsJsonArray.add(hostJsonObject)
}
val httpApi = NetService.instances.createHttps(HttpApi::class.java)
val hostsJsonArrayStr = hostsJsonArray.toString()
val hostsJsonArrayStrObject = JsonObject()
hostsJsonArrayStrObject.addProperty("requestLogs", hostsJsonArrayStr)
val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")
hostsJsonArrayStrObject.addProperty("phToken", phToken)
val encryptHostsJsonArrayStrObject = AESUtil.byteArrayToHexStr(
AESUtil.encrypt(hostsJsonArrayStrObject.toString())
)
// Log.d("encryptHostsJsonArrayStrObject==>$encryptHostsJsonArrayStrObject")
val requestBody: RequestBody = RequestBody.create(
"text/plain".toMediaTypeOrNull(), encryptHostsJsonArrayStrObject
)
val uploadRequestLogs = httpApi.uploadRequestLogs(requestBody)
Log.d("uploadRequestLogs==>${uploadRequestLogs}")
// if ("0" == uploadRequestLogs.code) {
// }
//登录失效
if (uploadRequestLogs.code == "-3") {
}
} catch (e: Exception) {
e.printStackTrace()
} finally {
hostsMem.clear()
isUpload = false
}
}
}
private val REQUEST_CODE_WRITE_STORAGE = 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.new_main_activity)
profileBinder =
MainApplication.getApp()?.let { ProfileManager(it).wrap() as IProfileManager }
clashBinder = MainApplication.getApp()?.let { ClashManager(it).wrap() as IClashManager }
// 文件权限请求
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.WRITE_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
REQUEST_CODE_WRITE_STORAGE
)
}
}
initViews()
mainAtyVM = ViewModelProvider(this)[MainAtyVM::class.java]
observe(this, mainAtyVM)
mainAtyVM.startHeartBeat()
mainAtyVM.getAirNodes()
mainAtyVM.getExpensesRecord(mPageInfo)
val isGlobal = MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_GLOBAL_MODEL, false)
newMainActGlo = isGlobal
startLog()
firstEntry()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val requestPermissionLauncher =
registerForActivityResult(
RequestPermission()
) { isGranted: Boolean ->
}
if (ContextCompat.checkSelfPermission(
this,
android.Manifest.permission.POST_NOTIFICATIONS
) != PackageManager.PERMISSION_GRANTED
) {
requestPermissionLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS)
}
}
//判断节点是否可以选择
mainAtyVM.getSelectNodeInfo()
}
/*
*活动弹窗
* */
private fun activityPopupWindow() {
mainAtyVM.getActivity()
}
private fun firstEntry() {
val decodeBool =
MMKV.defaultMMKV().decodeBool(BZYConstants.INITIALIZATION, false)
if ((decodeBool)) {
MaterialDialog(this).show {
cornerRadius(res = R.dimen.dp_10)
customView(
R.layout.first_entry_layout,
scrollable = false,
noVerticalPadding = true,
horizontalPadding = false
)
getCustomView().findViewById<TextView>(R.id.determine).setOnClickListener {
MMKV.defaultMMKV().encode(BZYConstants.INITIALIZATION, false)
dismiss()
}
}
} else {
mainAtyVM.getNoticeInfo()
activityPopupWindow()
}
}
fun startUploadTimer() {
stopUploadTimer()
if (timer == null) {
timer = Timer()
u_timerTask = object : TimerTask() {
override fun run() {
// Log.d("60s执行上传==>")
uploadLogHttp()
}
}
}
timer?.schedule(u_timerTask, 60000, 60000)
}
fun stopUploadTimer() {
timer?.cancel()
timer = null
u_timerTask?.cancel()
u_timerTask = null
}
private fun startLog() {
launch(Dispatchers.IO) {
// startForegroundServiceCompat(LogcatService::class.intent)
// val logcat = bindLogcatService()
// val ticker = ticker(500)
// var initial = true
// while (isActive) {
// select<Unit> {
// ticker.onReceive {
// val snapshot = logcat.snapshot(initial) ?: return@onReceive
// Log.i("startLog meessage==>${snapshot.messages}, removed==>${snapshot.removed}, appended==>${snapshot.appended}")
// initial = false
// }
// }
// }
val observer = object : ILogObserver {
override fun newItem(log: LogMessage) {
var msg = log.message
if (BuildConfig.DEBUG) {
Log.i("startLog msg==>${msg}")
}
var domain = Utils.getDomainNameFromString(msg)
// if (BuildConfig.DEBUG) {
// Log.i("startLog meessage==>${domain}")
// }
if (!TextUtils.isEmpty(domain)) {
addOrSendHost(domain!!)
}
}
}
clashBinder?.let {
it.setLogObserver(observer)
}
}
}
override fun httpLoading(httpStatus: HttpStatus.Loading) {
if (httpStatus.reqType == HttpReqType.HEARTBEAT) {
Logger.d("心跳中")
} else if (httpStatus.reqType == HttpReqType.CHECK_LOGIN) {
showLoadingDialog(resources.getString(R.string.QueryingPaymentResults))
}
}
override fun httpSuccess(httpStatus: HttpStatus.Success) {
Logger.d("心跳成功")
if (httpStatus.reqType == HttpReqType.HEARTBEAT) {
if (httpStatus.rsp is HeartBeatRsp) {
httpStatus.rsp.let {
val mmkv = MMKV.defaultMMKV()
when (it.code) {
0 -> {
mmkv.encode(BZYConstants.MMKV_KEY_VPN_EXPIRED, false)
HEART_BEAT_FAILURE_FREQUENCY = 0
}
-2 -> {
mmkv.encode(BZYConstants.MMKV_KEY_VPN_EXPIRED, false)
HEART_BEAT_FAILURE_FREQUENCY = 0
cleanUserInfo()
}
-4 -> {
mmkv.encode(BZYConstants.MMKV_KEY_VPN_EXPIRED, false)
HEART_BEAT_FAILURE_FREQUENCY = 0
cleanUserInfo()
}
}
}
}
} else if (httpStatus.reqType == HttpReqType.PHDOWNLOADURL) {
(httpStatus.rsp as PhDownloadUrlRsp).let {
if (it.code == 1000) {
val lastNotice =
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_NOTICE_READ, "")
val data = it.data
// if (data?.notice != null) {
// initMainPageHorseRaceLamp(data.notice)
// }
if (data?.notice != null && lastNotice != data.notice) {
val notice = data.notice
val dialog = DialogNotice(this@NewMainActivity, notice, data.downloadUrl)
dialog.setOnReadClickListener(object : DialogNotice.OnReadClickListener {
override fun onReadClick() {
MMKV.defaultMMKV()
.encode(BZYConstants.MMKV_KEY_NOTICE_READ, data.notice)
MMKV.defaultMMKV().encode(
BZYConstants.MMKV_KEY_NOTICE_DOWNLOAD_READ, data.downloadUrl
)
dialog.dismiss()
}
})
dialog.show()
}
}
}
} else if (httpStatus.reqType == HttpReqType.GetRuningNotice) {
(httpStatus.rsp as PhDownloadUrlRsp).let {
if (it.code == 1000) {
val data = it.data
if (data?.notice != null) {
initMainPageHorseRaceLamp(data.notice)
}
}
}
} else if (httpStatus.reqType == HttpReqType.CHECK_LOGIN) {
timerJob?.cancel()
(httpStatus.rsp as CheckLoginRsp).let { checkLoginRsp ->
if (checkLoginRsp.code == 0) {
val mmkv = MMKV.defaultMMKV()
val oldExpireTime = mmkv.decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD, 0)
val nowExpireTime = checkLoginRsp.data!!.vpnExpireTime
if (nowExpireTime > oldExpireTime) {
val expired = checkLoginRsp.data.expired
mmkv.encode(BZYConstants.MMKV_KEY_VPN_EXPIRED, expired ?: true)
mmkv.encode(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD, nowExpireTime)
setExpireDate()
fragments.filterIsInstance<NewAccFragment>().forEach { it.setExpireDate() }
checkPayResultDia?.dismiss()
mainAtyVM.getAirNodes()
RxToast.info(resources.getString(R.string.SuccessfullyUpdatedUserInformation))
} else {
// RxToast.info(resources.getString(R.string.PaymentResultsStr))
}
} else {
RxToast.info(resources.getString(R.string.QueryFailed))
}
payResultLoading?.dismiss()
}
} else if (httpStatus.reqType == HttpReqType.GET_AIRNODES) {
val data = httpStatus.rsp as SubscriptionRsp
if (data.code != "1000") {
RxToast.error(resources.getString(R.string.NodeAcquisitionFailed) + "${data.msg}")
}
data.data.let { url ->
android.util.Log.e("Data", "机场URL=${url}")
// var url2="https://api.ymvpnpro11.cc:8700/7air2vr7ikiqzgvxz/api/v1/client/subscribe?token=5af82930d222840cbc2dec572b21d6c6"
if (url.isNotEmpty()) {
//todo 判断订阅地址是否修改过,未修改就用接口返回的地址反之使用本地修改的地址
val proSubUrl =
MMKV.defaultMMKV().decodeString(BZYConstants.PROFILE_SUB_URL, "")
subUrl = if (!TextUtils.isEmpty(proSubUrl)) {
if (proSubUrl == url) {
url
} else {
proSubUrl
}
} else {
url
}
android.util.Log.i("AAAAAAAAAAA","pro_sub_url data:::"+proSubUrl+"::subUrl::"+ subUrl)
lifecycleScope.launch(Dispatchers.IO) {
subUrl?.let { setSub2(it) }
}
}
}
} else if (httpStatus.reqType == HttpReqType.VIPSIGN) {
val data = httpStatus.rsp as VipSignRsp
if (data.code == "1000") {
var gifMains = 30
data.data?.let {
if (it.signGiftmins != null) {
gifMains = it.signGiftmins;
}
}
RxToast.success(
resources.getString(R.string.SingInGive).replace("%d", "${gifMains}")
)
} else {
RxToast.error(resources.getString(R.string.CheckFailed) + "${data.message}")
}
} else if (httpStatus.reqType == HttpReqType.GetActivity) {
val data = httpStatus.rsp as GetActivityRsp
if (data.code == 200) {
if (data.data != null) {
if (data.data.data != null) {
if (data.data.data.list.isNotEmpty()) {
data.data.data.list[0].redirectLink.let {
if(activityDialog==null){
activityDialog =
ActivityViewDialog(this, data.data.data.list[0].redirectLink)
activityDialog?.setOnDialogClickListener(object :
OnDialogClickListener {
override fun onRechargeClickListener() {
//跳转到支付界面
goBackupRechargeWeb()
}
override fun onCancelClickListener() {
activityDialog?.dismiss()
}
})
activityDialog?.show()
}
}
}
}
}
}
}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>0){
tvTemporaryAccount.text=resources.getString(R.string.MemberAccount)
}else{
tvTemporaryAccount.text=resources.getString(R.string.TemporaryUser)
}
}else{
tvTemporaryAccount.text=resources.getString(R.string.TemporaryUser)
}
}else{
tvTemporaryAccount.text=resources.getString(R.string.TemporaryUser)
}
}else{
tvTemporaryAccount.text=resources.getString(R.string.TemporaryUser)
}
}
}
}else if(httpStatus.reqType == HttpReqType.SelectNode){
(httpStatus.rsp as ShowNode).let {
if (it.code == 200) {
val screenshotFlag = it.data?.screenshotFlag
screenshotFlag.let {
if (screenshotFlag == true) {
// 在 Activity 中取消禁止截屏/录屏
window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
MMKV.defaultMMKV().encode(
ScreenFlag,screenshotFlag
)
}else{
window.setFlags(
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE
)
MMKV.defaultMMKV().encode(
ScreenFlag,screenshotFlag!!
)
}
}
}
}
}
}
override fun httpFailure(httpStatus: HttpStatus.Failure) {
if (httpStatus.reqType == HttpReqType.HEARTBEAT) {
Logger.d("心跳失败")
if (5 <= HEART_BEAT_FAILURE_FREQUENCY) {
HEART_BEAT_FAILURE_FREQUENCY = 0
Logger.d("心跳失败次数超过10次退出登录")
cleanUserInfo()
}
HEART_BEAT_FAILURE_FREQUENCY++
} else if (httpStatus.reqType == HttpReqType.CHECK_LOGIN) {
payResultLoading?.dismiss()
RxToast.error(resources.getString(R.string.QueryFailed))
} else if (httpStatus.reqType == HttpReqType.GET_AIRNODES) {
Logger.e("获取节点异常:${httpStatus.msg}")
} else if (httpStatus.reqType == HttpReqType.VIPSIGN) {
RxToast.error(resources.getString(R.string.CheckFailed) + httpStatus.msg)
}
}
private fun initViews() {
containerVP = findViewById(R.id.container)
ivTor=findViewById(R.id.ivTor)
tvNetStr=findViewById(R.id.tvNetStr)
tvTemporaryAccount=findViewById(R.id.tvTemporaryAccount)
val selectedName =
MMKV.defaultMMKV().decodeString(BZYConstants.NODE_SELECTED_NAME_KEY, "自动选择")
tvNetStr.text=selectedName
containerVP.offscreenPageLimit = 1
if (fragments.isNotEmpty()) fragments.clear()
fragments.add(NewAccFragment())
// fragments.add(RechargeFragment())
containerVP.adapter = MainVPAdapter(fragments, supportFragmentManager, lifecycle)
containerVP.isUserInputEnabled = false
var aniAct = findViewById<LottieAnimationView>(R.id.lottie_activity)
aniAct.setAnimation(R.raw.activity)
aniAct.playAnimation()
aniAct.setOnClickListener {
startActivity(Intent(CommonUtils.getApp(), ActivityActivity::class.java))
}
findViewById<LinearLayout>(R.id.ll_activity).setOnClickListener {
startActivity(Intent(CommonUtils.getApp(), ActivityActivity::class.java))
}
setSometion()
}
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() {
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)
Log.d("cleanUserInfo clashRunning==>${clashRunning}")
if (clashRunning) {
stopClashService()
}
stopUploadTimer()
mainAtyVM.stopHeartBeat()
cleanProfile()
val intent = Intent(this, LoginActivity::class.java)
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(intent)
finish()
}
private fun cleanProfile() {
Log.d("cleanProfile start")
GlobalScope.launch(Dispatchers.IO) {
profileBinder?.let { pm ->
pm.queryAll().forEach { profile ->
Log.d("cleanProfile go delete name==>${profile.name}, uuid==>${profile.uuid}")
pm.delete(profile.uuid)
}
} ?: let {
Log.d("profileBinder is null")
}
}
}
fun setSometion() {
tv_expire_date = findViewById(R.id.tv_expire_date)
setExpireDate()
tv_username = findViewById(R.id.tv_username)
iv_slider = findViewById(R.id.iv_slider)
ll_slider = findViewById(R.id.ll_slider)
clExit=findViewById(R.id.clExit)
clExit.setOnClickListener {
cleanUserInfo()
}
ivTor.setOnClickListener {
startActivity(Intent(this@NewMainActivity, PersonalCenter::class.java))
drawer.close()
}
if (MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_IS_PERFECT)) {
tv_username.text = "ID${
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
}"
} else {
tv_username.text = "ID${
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
}"
}
findViewById<LinearLayout>(R.id.llOpenRechre).setOnClickListener {//充值
drawer.close()
goBackupRechargeWeb()
}
findViewById<ConstraintLayout>(R.id.clMessage).setOnClickListener {//通知
val notice =
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_NOTICE_READ, "暂无新通知")!!
val downloadUrl =
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_NOTICE_DOWNLOAD_READ, "")!!
val dialog = DialogNotice(this@NewMainActivity, notice, downloadUrl)
dialog.setOnReadClickListener(object : DialogNotice.OnReadClickListener {
override fun onReadClick() {
dialog.dismiss()
}
})
dialog.show()
drawer.close()
}
tv_username.setOnClickListener {
val userName = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
val clipboardManager = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clipData = ClipData.newPlainText("text", userName)
clipboardManager.setPrimaryClip(clipData)
RxToast.info(resources.getString(R.string.CopyToClipboard))
}
// tv_rechar.setOnClickListener {
// goRechargeWeb()
// }
findViewById<ConstraintLayout>(R.id.clLocation).setOnClickListener {
if (checkExpire()) {
RxToast.info(resources.getString(R.string.AccountExpired))
return@setOnClickListener
}
val intent = Intent(CommonUtils.getApp(), ChangeNodeActivity::class.java)
if (!TextUtils.isEmpty(newUuid)) {
intent.putExtra(BZYConstants.MMKV_KEY_CURRENT_NODE, newUuid)
intent.putExtra(BZYConstants.EXTRA_KEY_IS_RUNING, clashRunning)
}
startActivityForResult(intent, CHECK_NODE_REQUEST_CODE)
drawer.close()
}
findViewById<ConstraintLayout>(R.id.clShareKo).setOnClickListener {//分享
startActivity(Intent(this@NewMainActivity, ShareActivity::class.java))
drawer.close()
}
findViewById<ConstraintLayout>(R.id.clSetting).setOnClickListener {//设置
startActivity(Intent(this, SettingActivity::class.java))
drawer.close()
}
findViewById<ConstraintLayout>(R.id.clFire).setOnClickListener {
startActivity(Intent(this, SettingActivity::class.java))
drawer.close()
}
findViewById<ConstraintLayout>(R.id.clCustomerService).setOnClickListener {//客服
startActivity(Intent(this, CustomerServiceWebView::class.java))
drawer.close()
}
drawer = findViewById(R.id.drawer)
iv_slider.setOnClickListener {
if (containerVP.currentItem != 0) {
iv_slider.setImageResource(R.mipmap.home_setting)
containerVP.setCurrentItem(0, true)
} else {
drawer.openDrawer(GravityCompat.START)
}
}
}
var checkPayResultDia: MaterialDialog? = null
var checkBindAccountDia: MaterialDialog? = null
public fun goRechargeWeb() {
val mmkv = MMKV.defaultMMKV()
val a = mmkv.decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")
val b = mmkv.decodeString(BZYConstants.MMKV_KEY_USER_ID, "")
val c = mmkv.decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")
val intent = Intent(this@NewMainActivity, BZYWebViewNormal::class.java)
val rcURL = NetService.getCurrentUrl() + "/78zccgy0nsgknh9n4/recharge?a=$a&b=$b&c=$c&d=2"
// val rcURL = "https://api.gaogaoshot.cc:18001" + "/78zccgy0nsgknh9n4/recharge?a=$a&b=$b&c=$c&d=2"
Log.d("rcURL==>${rcURL}")
intent.putExtra("url", rcURL)
// startActivity(intent)
startActivityForResult(intent, REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY)
}
fun goBackupRechargeWeb() {
startActivityForResult(
Intent(this@NewMainActivity, MemberRechargeActivity::class.java),
REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY
)
}
fun goCheckLogin() {
mainAtyVM.checkLogin()
}
private fun showBindAccount() {
val userAccount =
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!!
if (Utils.isEmail(userAccount) || Utils.isPhoneNumber(userAccount)) {
return
}
checkBindAccountDia = MaterialDialog(this).show {
this.cancelable(false)
cornerRadius(res = R.dimen.dp_10)
customView(
R.layout.bind_account_dialog_layout,
scrollable = false,
noVerticalPadding = true,
horizontalPadding = false
)
getCustomView().findViewById<TextView>(R.id.tv_pay_finish).setOnClickListener {
//跳转到绑定邮箱界面
showBingDialogChoose()
dismiss()
}
getCustomView().findViewById<TextView>(R.id.tv_pay_cancle).setOnClickListener {
dismiss()
}
}
}
private fun showBingDialogChoose() {
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()
}
private fun showLoadingDialog(msg: String) {
payResultLoading = RxDialogShapeLoading(this)
payResultLoading!!.setMessage(msg)
payResultLoading!!.show()
loadingTimeoutNum = 3
timerJob = launch {
repeat(4) {
Log.d("loadingTimeoutNum==>${loadingTimeoutNum}")
if (loadingTimeoutNum == 0) {
payResultLoading?.dismiss()
}
loadingTimeoutNum--
delay(1000)
}
}
}
override fun onBackPressed() {
if (containerVP.currentItem != 0) {
iv_slider.setImageResource(R.drawable.ic_s_menu)
containerVP.setCurrentItem(0, true)
} else {
val backHome = Intent(Intent.ACTION_MAIN)
backHome.flags = Intent.FLAG_ACTIVITY_NEW_TASK
backHome.addCategory(Intent.CATEGORY_HOME)
startActivity(backHome)
return
}
super.onBackPressed()
}
private fun checkExpire(): Boolean {
val validPeriod = MMKV.defaultMMKV().decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD)
if (validPeriod > 0) {
val nowTime = System.currentTimeMillis()
Log.d("validPeriod==>$validPeriod, nowTime==>$nowTime")
if (validPeriod >= nowTime) {
return false
}
}
return true;
}
@SuppressLint("SimpleDateFormat", "SetTextI18n")
fun setExpireDate() {
val isExpire = checkExpire()
var endTimeInfo = "--"
if (isExpire) {
endTimeInfo = resources.getString(R.string.AccountExpired)
} else {
val validPeriod = MMKV.defaultMMKV().decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD)
val decodeString = MMKV.defaultMMKV().decodeString(BZYConstants.languageInfo, "")
if (decodeString.isNullOrEmpty()) {
//获取当前系统语言
val config = resources.configuration
val language = config.locale.language
if (language.equals("en")) {
val dateFormat = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val locale = Locale.ENGLISH
SimpleDateFormat("MM/dd/yyyy HH:mm", locale)
} else {
val locale = Locale.ENGLISH
SimpleDateFormat("MM/dd/yyyy HH:mm", locale)
}
endTimeInfo = dateFormat.format(validPeriod)
} else {
val dateFormat = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
SimpleDateFormat("yyyy年MM月dd日 HH:mm")
} else {
SimpleDateFormat("yyyy年MM月dd日 HH:mm")
}
endTimeInfo = dateFormat.format(validPeriod)
}
} else {
if (decodeString == "English") {
val dateFormat = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val locale = Locale.ENGLISH
SimpleDateFormat("MM/dd/yyyy HH:mm", locale)
} else {
val locale = Locale.ENGLISH
SimpleDateFormat("MM/dd/yyyy HH:mm", locale)
}
endTimeInfo = dateFormat.format(validPeriod)
} else {
val dateFormat = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
SimpleDateFormat("yyyy年MM月dd日 HH:mm")
} else {
SimpleDateFormat("yyyy年MM月dd日 HH:mm")
}
endTimeInfo = dateFormat.format(validPeriod)
}
}
}
tv_expire_date.text = endTimeInfo
}
override fun onRequestPermissionsResult(
requestCode: Int, permissions: Array<out String>, grantResults: IntArray,
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == REQUEST_CODE_WRITE_STORAGE) {
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
// 权限授予,执行下载操作
} else {
// 权限拒绝,处理相应逻辑
// 提示用户权限被拒绝
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// 显示提示信息
RxToast.info(resources.getString(R.string.giveMyPermission))
}
}
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY) {
if (activityDialog != null) {
activityDialog?.dismiss()
}
goCheckLogin()
showBindAccount()
}else if(requestCode == CHECK_NODE_REQUEST_CODE){
fragments.filterIsInstance<NewAccFragment>().forEach { it.nodeChooseBase(data) }
val selectedName =
MMKV.defaultMMKV().decodeString(BZYConstants.NODE_SELECTED_NAME_KEY, "自动选择")
tvNetStr.text=selectedName
}
}
override fun onDestroy() {
if (activityDialog != null) {
if(activityDialog!!.isShowing){
activityDialog!!.dismiss()
}
}
super.onDestroy()
stopUploadTimer()
mainAtyVM.stopHeartBeat()
}
class PageInfo {
var page = 1
fun nextPage() {
page++
}
fun reset() {
page = 1
}
val isFirstPage: Boolean
get() = page == 1
}
}