1036 lines
44 KiB
Kotlin
1036 lines
44 KiB
Kotlin
package com.yingmao.clash.act
|
||
|
||
import android.Manifest
|
||
import android.annotation.SuppressLint
|
||
import android.content.Intent
|
||
import android.content.pm.PackageManager
|
||
import android.graphics.Bitmap
|
||
import android.graphics.drawable.BitmapDrawable
|
||
import android.net.Uri
|
||
import android.os.Build
|
||
import android.os.Bundle
|
||
import android.provider.Settings
|
||
import android.text.TextUtils
|
||
import android.util.Log
|
||
import android.view.View
|
||
import android.view.WindowManager
|
||
import android.widget.ProgressBar
|
||
import android.widget.RelativeLayout
|
||
import android.widget.TextView
|
||
import android.widget.Toast
|
||
import androidx.annotation.RequiresApi
|
||
import androidx.core.app.ActivityCompat
|
||
import androidx.core.content.ContextCompat
|
||
import androidx.core.content.FileProvider
|
||
import androidx.lifecycle.ViewModelProvider
|
||
import com.afollestad.materialdialogs.MaterialDialog
|
||
import com.afollestad.materialdialogs.customview.customView
|
||
import com.bumptech.glide.Glide
|
||
import com.bumptech.glide.request.target.SimpleTarget
|
||
import com.bumptech.glide.request.transition.Transition
|
||
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.captcha.Captcha
|
||
import com.yingmao.clash.conf.BZYConstants
|
||
import com.yingmao.clash.conf.BZYConstants.Companion.MMKV_KEY_IS_REGISTER
|
||
import com.yingmao.clash.conf.BZYConstants.Companion.MMKV_KEY_NOTE_DEFAULT_PSW
|
||
import com.yingmao.clash.conf.BZYConstants.Companion.MMKV_KEY_REMEMBER_PASSWORD
|
||
import com.yingmao.clash.conf.BZYConstants.Companion.MMKV_KEY_REMEMBER_USERNAME
|
||
import com.yingmao.clash.entity.CheckLoginRsp
|
||
import com.yingmao.clash.listener.AsyncCallback
|
||
import com.yingmao.clash.net.http.HttpReqType
|
||
import com.yingmao.clash.net.http.HttpStatus
|
||
import com.yingmao.clash.net.http.entity.LoginRsp
|
||
import com.yingmao.clash.net.http.entity.RegisterRsp
|
||
import com.cncat.vpn.service.ClashManager
|
||
import com.cncat.vpn.service.remote.IClashManager
|
||
import com.cncat.vpn.service.remote.wrap
|
||
import com.yingmao.clash.listener.DownLoadListener
|
||
import com.yingmao.clash.net.http.entity.AppVersionCheckRsp
|
||
import com.yingmao.clash.net.http.entity.StartingBeans
|
||
import com.yingmao.clash.util.AESUtil
|
||
import com.yingmao.clash.util.Utils
|
||
import com.yingmao.clash.view.RxToast
|
||
import com.yingmao.clash.view.dialog.DialogAppVersion
|
||
import com.yingmao.clash.view.dialog.DialogBandChoose
|
||
import com.yingmao.clash.view.dialog.DialogDoMainChoose
|
||
import com.yingmao.clash.view.dialog.RxDialogSureCancel
|
||
import com.yingmao.clash.vm.SplashAtyVM
|
||
import kotlinx.coroutines.MainScope
|
||
import kotlinx.coroutines.launch
|
||
import java.io.File
|
||
import java.util.Locale
|
||
import androidx.lifecycle.lifecycleScope
|
||
import kotlinx.coroutines.async
|
||
class SplashActivity : BaseActivity() {
|
||
|
||
private val deniedPermissions = hashSetOf<String>()
|
||
private val mPermissions = hashSetOf<String>()
|
||
private val PERMISSION_REQUEST_CODE: Int = 1
|
||
private val PERMISSION_SETTING_REQUEST_CODE = 2
|
||
private lateinit var rlPb: View
|
||
private lateinit var ll_action: View
|
||
private lateinit var username: String
|
||
private lateinit var rlMain: RelativeLayout
|
||
|
||
private lateinit var splashAtyVM: SplashAtyVM
|
||
private var registerKey = ""
|
||
private var registerIV2 = ""
|
||
|
||
private var initErrMsg = ""
|
||
override fun onCreate(savedInstanceState: Bundle?) {
|
||
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
|
||
super.onCreate(savedInstanceState)
|
||
|
||
setLocalLanguage()
|
||
initErrMsg = resources.getString(R.string.splashErrorTips)
|
||
username = Utils.getUniqueID(this)
|
||
// var username2 = Utils.getUniqueID2(this);
|
||
// com.cncat.vpn.common.log.Log.d("username==>" + username + ", username2==>" + username2)
|
||
splashAtyVM = ViewModelProvider(this).get(SplashAtyVM::class.java)
|
||
observe(this, splashAtyVM)
|
||
setContentView(R.layout.layout_splash_activity)
|
||
rlMain=findViewById(R.id.rlMain)
|
||
|
||
rlPb = findViewById(R.id.rl_pb)
|
||
ll_action = findViewById(R.id.ll_action)
|
||
serStore.isYM = BuildConfig.is_ym
|
||
if (!BuildConfig.is_ym) {
|
||
if (BuildConfig.is_tz) {
|
||
serStore.isTZ = true
|
||
} else {
|
||
serStore.isBZY = true
|
||
}
|
||
}
|
||
|
||
|
||
// mPermissions.add(Manifest.permission.READ_PHONE_STATE)
|
||
// mPermissions.add(Manifest.permission.INTERNET)
|
||
// mPermissions.add(Manifest.permission.ACCESS_NETWORK_STATE)
|
||
// if (checkPermissions(mPermissions)) {//权限请求通过
|
||
// Log.e("gg", "per sss")
|
||
// } else {//权限请求未通过
|
||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||
// requestPermissions(mPermissions.toTypedArray(), PERMISSION_REQUEST_CODE)
|
||
// }
|
||
// }
|
||
|
||
// OpenInstall.getInstall(object : AppInstallListener {
|
||
// override fun onInstallFinish(
|
||
// appData: AppData?,
|
||
// error: com.fm.openinstall.model.Error?,
|
||
// ) {
|
||
// var mAppData = appData
|
||
// if (error != null && error.shouldRetry()) {
|
||
// // 获取数据异常,可以尝试重新获取
|
||
// } else {
|
||
// if (mAppData == null) mAppData = AppData()
|
||
// val channelCode = mAppData.getChannel() // 获取渠道编号参数
|
||
// val bindData = mAppData.getData() // 获取自定义参数
|
||
// com.cncat.vpn.common.log.Log.d("channelCode==>${channelCode}, bindData==>${bindData}")
|
||
// }
|
||
// }
|
||
// })
|
||
|
||
|
||
// DeviceID.getOAID(this, object : IGetter {
|
||
// override fun onOAIDGetComplete(result: String) {
|
||
// // 不同厂商的OAID/AAID格式是不一样的,可进行MD5、SHA1之类的哈希运算统一
|
||
// com.cncat.vpn.common.log.Log.d("onOAIDGetComplete result==>${result}")
|
||
// }
|
||
//
|
||
// override fun onOAIDGetError(error: Exception) {
|
||
// // 获取OAID/AAID失败
|
||
// error.printStackTrace()
|
||
// }
|
||
// })
|
||
|
||
|
||
// com.cncat.vpn.common.log.Log.d("onOAIDGetComplete result==>${ DeviceIdentifier.getOAID(this)}")
|
||
//获取配置背景
|
||
splashAtyVM.getSplashBg()
|
||
var clashBinder = MainApplication.getApp()?.let {
|
||
ClashManager(it).wrap() as IClashManager
|
||
}
|
||
clashBinder?.let { cb ->
|
||
var signList =
|
||
AESUtil.getSingInfo(this@SplashActivity, BuildConfig.applicationId, AESUtil.SHA256)
|
||
if (signList.isNotEmpty()) {
|
||
var si = signList[0]
|
||
var ss1 = cb.getSS1(si)
|
||
var ss2 = cb.getSS2(si)
|
||
registerKey = cb.getRegisterKey(si)
|
||
registerIV2 = cb.getRegisterKiv(si)
|
||
// com.cncat.vpn.common.log.Log.d("si==>${si}, ss1==>${ss1}, ss2==>${ss2}")
|
||
AESUtil.KEY2 = ss1
|
||
AESUtil.IV2 = ss2
|
||
// 太子
|
||
// com.cncat.vpn.common.log.Log.d("tz encrypt:"+ AESUtil.byteArrayToHexStr(AESUtil.encrypt("")))
|
||
// 八爪鱼 com.cncat.vpn.common.log.Log.d("bzy encrypt:"+ AESUtil.byteArrayToHexStr(AESUtil.encrypt("")))
|
||
// 八爪鱼 2
|
||
// com.cncat.vpn.common.log.Log.d("bzy2 encrypt:"+ AESUtil.byteArrayToHexStr(AESUtil.encrypt("")))
|
||
// 影猫
|
||
// com.cncat.vpn.common.log.Log.d(
|
||
// "ym encrypt:" +
|
||
// AESUtil.byteArrayToHexStr(
|
||
// AESUtil.encrypt(
|
||
// "https://api.yingmaohot.org+https://api.yingmao888.net+" +
|
||
// "https://api.ymsohot.com+https://ma.wztgyh.com+https://ymapi.yingmaox.cc"
|
||
// )
|
||
// )
|
||
// )
|
||
val routerSet =
|
||
MMKV.defaultMMKV().decodeStringSet(BZYConstants.MMKV_KEY_ROUTER_HOST)
|
||
if (routerSet != null && routerSet.size > 0) {
|
||
isNeedRegister()
|
||
} else {
|
||
rlPb.visibility = View.VISIBLE
|
||
if (BuildConfig.is_back_cn == true) { //没有备用域名所以无需调用getHost
|
||
isNeedRegister()
|
||
} else {
|
||
SplashHelper(splashAtyVM).getHostWithFallback { success ->
|
||
MainScope().launch {
|
||
if (success) {
|
||
isNeedRegister()
|
||
} else {
|
||
isNeedRegister()
|
||
}
|
||
}
|
||
}
|
||
// splashAtyVM.getHostByGithub(object : AsyncCallback {
|
||
// override suspend fun suc() {
|
||
// Log.e("data", "getHostByGithub suc")
|
||
// MainScope().launch {
|
||
// isNeedRegister()
|
||
// }
|
||
// }
|
||
//
|
||
// override fun err() {
|
||
// Log.e("data", "getHostByGithub err")
|
||
// splashAtyVM.getHostByAWS(object : AsyncCallback {
|
||
// override suspend fun suc() {
|
||
// Log.e("data", "getHostByAWS suc")
|
||
// MainScope().launch {
|
||
// isNeedRegister()
|
||
// }
|
||
// }
|
||
//
|
||
// override fun err() {
|
||
// Log.e("data", "getHostByAWS err")
|
||
// splashAtyVM.getHost(object : AsyncCallback {
|
||
// override suspend fun suc() {
|
||
// Log.e("data", "getHost suc")
|
||
// MainScope().launch {
|
||
// isNeedRegister()
|
||
// }
|
||
// }
|
||
//
|
||
// override fun err() {
|
||
// Log.e("data", "getHost err")
|
||
// //全部失败后也调用
|
||
// MainScope().launch {
|
||
// isNeedRegister()
|
||
// }
|
||
// }
|
||
// })
|
||
// }
|
||
// })
|
||
// }
|
||
// })
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// val Sgtr= AESUtil.Registerdecrypt("CCBF308D702235C8F810876987A43AB02B84EBB47DBFF1B915D5FBB29FF2DBAE90DB72D58351D09D223D49E44A2A073D9156E84D6B7EB89D7493A3F0A7240EE076ADC83B5A12AC37616CEDED00643AD1E6851AFECA82E373CB4E518DF2190708F5191AE195758E8EA41A5242A6C94216B64FF8715B35C54CB894113FC93361F32FDA86CF34093DF924230DEBE27A69293C761A9A797A652A1C35C95C27FB5EB4"
|
||
// ,registerKey,registerIV2)
|
||
// println("Sgtr==>$Sgtr")
|
||
}
|
||
|
||
private fun setLocalLanguage() {
|
||
var defLan = ""
|
||
if (BuildConfig.is_tz) {
|
||
defLan = "Chinese-HK"
|
||
}
|
||
val decodeString = MMKV.defaultMMKV().decodeString(BZYConstants.languageInfo, defLan)
|
||
if (!decodeString.isNullOrEmpty()) {
|
||
when (decodeString) {
|
||
"Chinese-CN" -> {
|
||
val config = resources.configuration
|
||
config.locale = Locale.CHINA
|
||
updateLanguage("Chinese-CN", Locale.CHINA)
|
||
}
|
||
|
||
"Chinese-HK" -> {
|
||
val config = resources.configuration
|
||
config.locale = Locale("zh", "HK")
|
||
updateLanguage("Chinese-HK", Locale("zh", "HK"))
|
||
}
|
||
|
||
"English" -> {
|
||
val config = resources.configuration
|
||
config.locale = Locale.ENGLISH
|
||
updateLanguage("English", Locale.ENGLISH)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private fun checkPermission(): Boolean {
|
||
if (ContextCompat.checkSelfPermission(
|
||
this,
|
||
Manifest.permission.ACCESS_NETWORK_STATE
|
||
) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(
|
||
this,
|
||
Manifest.permission.INTERNET
|
||
) == PackageManager.PERMISSION_GRANTED
|
||
) {
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
override fun 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() {
|
||
if (!BuildConfig.is_free && BuildConfig.productId.isNotEmpty()) { //渠道包都自动注册登录,广州22222也是非自动注册
|
||
rlPb.visibility = View.VISIBLE
|
||
if (MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_IS_REGISTER, false)) {
|
||
splashAtyVM.checkLogin()
|
||
} else {
|
||
// doRegister()
|
||
doRegisterByEncryption()
|
||
}
|
||
} else {//非渠道自由包
|
||
val token = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_TOKEN)
|
||
ll_action.visibility = View.VISIBLE
|
||
rlPb.visibility = View.INVISIBLE
|
||
if (MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_IS_REGISTER, false)) {
|
||
if (token != null && token.isNotEmpty()) {
|
||
ll_action.visibility = View.GONE
|
||
rlPb.visibility = View.VISIBLE
|
||
splashAtyVM.checkLogin()
|
||
} else {
|
||
val intent = Intent(this@SplashActivity, LoginActivity::class.java)
|
||
startActivity(intent)
|
||
finish()
|
||
}
|
||
} else {
|
||
findViewById<View>(R.id.rl_action_login).setOnClickListener {//点有账号直接登录的
|
||
val intent = Intent(this@SplashActivity, LoginActivity::class.java)
|
||
startActivity(intent)
|
||
finish()
|
||
}
|
||
findViewById<View>(R.id.rl_action_register).setOnClickListener {//无账号的自动注册但不会填任何渠道号
|
||
val intent = Intent(this@SplashActivity, RegisterActivity::class.java)
|
||
startActivity(intent)
|
||
finish()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
var errorTotal: Int = 0
|
||
fun doRegister() {
|
||
val params: Map<String, String> = mutableMapOf(
|
||
"phoneNumber" to username,
|
||
"password" to BZYConstants.defaultPassword,
|
||
"checkPassword" to BZYConstants.defaultPassword,
|
||
"id" to BuildConfig.productId,
|
||
"clientIp" to Utils.getIPAddress(),
|
||
"from" to "5",
|
||
)
|
||
splashAtyVM.register(params)
|
||
}
|
||
|
||
@Synchronized
|
||
fun doRegisterByEncryption() {
|
||
|
||
var req_json = JsonObject()
|
||
req_json.addProperty("password", BZYConstants.defaultPassword)
|
||
req_json.addProperty("checkPassword", BZYConstants.defaultPassword)
|
||
req_json.addProperty("invitationCode", BuildConfig.productId)
|
||
req_json.addProperty("clientIp", Utils.getIPAddress())
|
||
req_json.addProperty("from", "5")
|
||
req_json.addProperty("androidDevice", username)
|
||
if (registerKey.isNotEmpty() && registerIV2.isNotEmpty()) {
|
||
val data = AESUtil.byteArrayToHexStr(
|
||
AESUtil.RegisterEncrypt(req_json.toString(), registerKey, registerIV2)
|
||
)
|
||
val params: Map<String, String> = mutableMapOf(
|
||
"data" to data
|
||
)
|
||
splashAtyVM.registerByEncryption(params)
|
||
}
|
||
}
|
||
// private fun initSub() {
|
||
// var yaml = context?.getString(com.cncat.vpn.service.R.string.configuration_yaml)
|
||
// Log.d(Conf.TAG, "initSub: $yaml")
|
||
//
|
||
// accelerateViewModel.statusData.observe(viewLifecycleOwner) {
|
||
// when (it) {
|
||
// is HttpStatus.Loading -> {
|
||
//
|
||
// Log.d(Conf.TAG, "正在获取节点信息...")
|
||
// }
|
||
//
|
||
// is HttpStatus.Success -> {
|
||
//
|
||
// val data = it.rsp as SubscriptionRsp
|
||
// if (data.code == "1000") {
|
||
//
|
||
// } else {
|
||
//// dismissDialog()
|
||
// RxToast.error("获取节点失败:${data.msg}")
|
||
// }
|
||
//
|
||
// data.data?.let { url ->
|
||
// Log.e("Data", "机场URL:=${url}")
|
||
// if (url.isNotEmpty()) {
|
||
//// lifecycleScope.launch {
|
||
////
|
||
//// }
|
||
//// sendMessage(1, url)
|
||
// setSub(url)
|
||
//
|
||
// }
|
||
// }
|
||
//
|
||
//// }
|
||
// }
|
||
//
|
||
// is HttpStatus.Failure -> {
|
||
// if (it.reqType == HttpReqType.GET_AIRNODES) {
|
||
//// dismissDialog()
|
||
//// showRetryDialog()
|
||
// Logger.e("获取节点异常:${it.msg}")
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
// private fun setSub(url: String) {
|
||
// com.cncat.vpn.common.log.Log.d("setSub....")
|
||
//
|
||
// lifecycleScope.launch (Dispatchers.IO) {
|
||
// com.cncat.vpn.common.log.Log.d("setSub....11")
|
||
// withProfile {
|
||
// com.cncat.vpn.common.log.Log.d("setSub....2")
|
||
// val pro = queryAll().find {
|
||
// it.name == "八爪猫"
|
||
// }
|
||
//
|
||
// if (pro == null) {
|
||
// com.cncat.vpn.common.log.Log.d("setSub.... pro is null")
|
||
// var uuid: UUID = create(Profile.Type.Url, "八爪猫")
|
||
// delay(500)
|
||
// queryByUUID(uuid)?.let { qPro ->
|
||
// setActive(qPro)
|
||
// 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",
|
||
// url, 1800000L
|
||
// )
|
||
//// coroutineScope {
|
||
// commit(qPro.uuid) { status ->
|
||
// Log.d(
|
||
// Conf.TAG,
|
||
// "new updateStatus: " + Gson().toJson(status.args) + ", pro==>" + status.progress
|
||
// )
|
||
// }
|
||
// newUuid = qPro.uuid.toString();
|
||
// isSubed = true
|
||
//// }
|
||
// }
|
||
// } else {
|
||
// Log.d(Conf.TAG, "pro 已存在 ==>" + Gson().toJson(pro))
|
||
// setActive(pro)
|
||
//// update(pro.uuid)
|
||
// newUuid = pro.uuid.toString();
|
||
// isSubed = true
|
||
// }
|
||
// profile = pro;
|
||
// }
|
||
// }
|
||
//
|
||
// }
|
||
|
||
override fun httpSuccess(httpStatus: HttpStatus.Success) {
|
||
when (httpStatus.reqType) {
|
||
HttpReqType.REGISTER -> {
|
||
dialogDoMainChoose?.dismiss()
|
||
with(httpStatus.rsp as RegisterRsp) {
|
||
if (code == "10000" || code == "200") {
|
||
if (data != null) {
|
||
if (!data.phoneNumber.isNullOrEmpty()) {
|
||
MMKV.defaultMMKV()
|
||
.encode(MMKV_KEY_REMEMBER_USERNAME, data.phoneNumber)
|
||
} else {
|
||
MMKV.defaultMMKV().encode(MMKV_KEY_REMEMBER_USERNAME, username)
|
||
}
|
||
} else {
|
||
MMKV.defaultMMKV().encode(MMKV_KEY_REMEMBER_USERNAME, username)
|
||
}
|
||
MMKV.defaultMMKV()
|
||
.encode(MMKV_KEY_REMEMBER_PASSWORD, BZYConstants.defaultPassword)
|
||
MMKV.defaultMMKV().encode(MMKV_KEY_IS_REGISTER, true)
|
||
MMKV.defaultMMKV().encode(MMKV_KEY_NOTE_DEFAULT_PSW, true)
|
||
val encryName = AESUtil.byteArrayToHexStr(
|
||
AESUtil.encrypt(data?.phoneNumber)
|
||
)
|
||
val encryPsw = AESUtil.byteArrayToHexStr(
|
||
AESUtil.encrypt(BZYConstants.defaultPassword)
|
||
)
|
||
val decodeBool =
|
||
MMKV.defaultMMKV().decodeBool(BZYConstants.INITIALIZATION, true)
|
||
if (decodeBool) {
|
||
MMKV.defaultMMKV().encode(BZYConstants.INITIALIZATION, true)
|
||
}
|
||
splashAtyVM.login(encryName, encryPsw)
|
||
} else if (code == "20062") {
|
||
message?.let {
|
||
RxToast.error(it)
|
||
}
|
||
// if (data != null) {
|
||
//
|
||
// var jo =
|
||
// Gson().fromJson<JsonObject>(data, JsonObject::class.java)
|
||
// var userName = jo.get("data").asString;
|
||
// if (!TextUtils.isEmpty(userName)) {
|
||
//
|
||
// }
|
||
// }
|
||
if (data != null) {
|
||
if (!data.phoneNumber.isNullOrEmpty()) {
|
||
MMKV.defaultMMKV()
|
||
.encode(MMKV_KEY_REMEMBER_USERNAME, data.phoneNumber)
|
||
} else {
|
||
MMKV.defaultMMKV().encode(MMKV_KEY_REMEMBER_USERNAME, username)
|
||
}
|
||
} else {
|
||
MMKV.defaultMMKV().encode(MMKV_KEY_REMEMBER_USERNAME, username)
|
||
}
|
||
val intent = Intent(this@SplashActivity, LoginActivity::class.java)
|
||
startActivity(intent)
|
||
finish()
|
||
// graphicVerificationDialog()
|
||
} else {
|
||
MaterialDialog(this@SplashActivity).show {
|
||
message(text = initErrMsg)
|
||
positiveButton(R.string.retry) {
|
||
// doRegister()
|
||
doRegisterByEncryption()
|
||
}
|
||
negativeButton(R.string.cancel) {
|
||
it.dismiss()
|
||
finish()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
HttpReqType.LOGIN -> {
|
||
val rsp = httpStatus.rsp
|
||
if (rsp is LoginRsp) {
|
||
if (rsp.code == "1000") {
|
||
val mmkv = MMKV.defaultMMKV()
|
||
com.cncat.vpn.common.log.Log.i(" HttpReqType.LOGIN token ==> ${rsp.data?.vpnToken}")
|
||
mmkv.encode(BZYConstants.MMKV_KEY_TOKEN, rsp.data?.vpnToken)
|
||
mmkv.encode(BZYConstants.MMKV_KEY_PH_TOKEN, rsp.data?.phToken)
|
||
mmkv.encode(BZYConstants.MMKV_KEY_USER_ID, rsp.data?.userId)
|
||
splashAtyVM.checkLogin()
|
||
} else {
|
||
MaterialDialog(this@SplashActivity).show {
|
||
message(text = initErrMsg)
|
||
positiveButton(R.string.retry) {
|
||
val encryName = AESUtil.byteArrayToHexStr(
|
||
AESUtil.encrypt(username)
|
||
)
|
||
val encryPsw = AESUtil.byteArrayToHexStr(
|
||
AESUtil.encrypt(BZYConstants.defaultPassword)
|
||
)
|
||
splashAtyVM.login(encryName, encryPsw)
|
||
}
|
||
negativeButton(R.string.cancel) {
|
||
it.dismiss()
|
||
finish()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
HttpReqType.CHECK_LOGIN -> {
|
||
dialogDoMainChoose?.dismiss()
|
||
(httpStatus.rsp as CheckLoginRsp).let { checkLoginRsp ->
|
||
if (checkLoginRsp.code == 0) {
|
||
com.cncat.vpn.common.log.Log.d("splash CHECK_LOGIN==>")
|
||
checkLoginRsp.data?.let { MainApplication.setUserInfo(it) }
|
||
val expired = checkLoginRsp.data?.expired
|
||
val isPerfect = checkLoginRsp.data?.isPerfect
|
||
val userCommand = checkLoginRsp.data?.userCommand
|
||
val mmkv = MMKV.defaultMMKV()
|
||
mmkv.encode(BZYConstants.MMKV_KEY_VPN_EXPIRED, expired ?: true)
|
||
mmkv.encode(
|
||
BZYConstants.MMKV_KEY_VPN_VALID_PERIOD,
|
||
checkLoginRsp.data?.vpnExpireTime ?: 0
|
||
)
|
||
mmkv.encode(BZYConstants.MMKV_KEY_IS_PERFECT, isPerfect ?: true)
|
||
mmkv.encode(BZYConstants.MMKV_KEY_VPN_UserCommand, userCommand ?: "")
|
||
|
||
|
||
toMainPage()
|
||
|
||
|
||
} else {
|
||
toLoginPage()
|
||
}
|
||
}
|
||
}
|
||
HttpReqType.SplashBg->{
|
||
val startingBeans = httpStatus.rsp as StartingBeans
|
||
startingBeans.data
|
||
if(startingBeans.data!=null){
|
||
if(startingBeans.data!!.exist){
|
||
Log.d("SplashActivityStarting","startingBeans.data!!.img::"+ startingBeans.data!!.img)
|
||
startingBeans.data!!.img.let {
|
||
Glide.with(this).asBitmap()
|
||
.load(startingBeans.data!!.img)
|
||
.into(object :SimpleTarget<Bitmap>(){
|
||
override fun onResourceReady(
|
||
resource: Bitmap,
|
||
transition: Transition<in Bitmap>?
|
||
) {
|
||
val bitmapDrawable = BitmapDrawable(resource)
|
||
rlMain.setBackgroundDrawable(bitmapDrawable)
|
||
}
|
||
|
||
})
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
}
|
||
HttpReqType.App_VERION_CHECK->{
|
||
(httpStatus.rsp as AppVersionCheckRsp).let { avcr ->
|
||
com.cncat.vpn.common.log.Log.i("App_VERION_CHECK ==>$avcr")
|
||
if (avcr.code == 200) {
|
||
avcr.data?.let { md ->
|
||
if (md.isForce) { //强制更新
|
||
if (!TextUtils.isEmpty(md.versionPath)) {
|
||
showUpdateDialog(md.versionPath!!, md.illustrate!!, true)
|
||
}
|
||
} else if (md.isUpgrade) { //更新
|
||
if (!TextUtils.isEmpty(md.versionPath)) {
|
||
showUpdateDialog(md.versionPath!!, md.illustrate!!, false)
|
||
}
|
||
}else{
|
||
val intent = Intent(this@SplashActivity, UIMainActivity::class.java)
|
||
startActivity(intent)
|
||
finish()
|
||
}
|
||
}
|
||
}else{
|
||
val intent = Intent(this@SplashActivity, UIMainActivity::class.java)
|
||
startActivity(intent)
|
||
finish()
|
||
}
|
||
}
|
||
}
|
||
|
||
else -> {}
|
||
}
|
||
}
|
||
|
||
var dialogDoMainChoose: DialogDoMainChoose? = null
|
||
override fun httpFailure(httpStatus: HttpStatus.Failure) {
|
||
when (httpStatus.reqType) {
|
||
HttpReqType.REGISTER -> {
|
||
rlPb.visibility = View.GONE
|
||
|
||
com.cncat.vpn.common.log.Log.d("httpFailure HttpReqType.REGISTER")
|
||
try {
|
||
RxToast.error("检测到网络异常,请尝试切换其他地址.")
|
||
if (dialogDoMainChoose==null) {
|
||
dialogDoMainChoose = DialogDoMainChoose(this@SplashActivity)
|
||
}
|
||
if (dialogDoMainChoose?.isShowing==false){
|
||
dialogDoMainChoose?.setOnTryButtonListener(object :
|
||
DialogDoMainChoose.OnTryButtonListener {
|
||
override fun tryButton() {
|
||
var currentHost = MMKV.defaultMMKV()
|
||
.decodeString(BZYConstants.MMKV_KEY_CURRENT_HOST, "")
|
||
// com.cncat.vpn.common.log.Log.d("tryButton currentHost==>${currentHost}")
|
||
doRegisterByEncryption()
|
||
}
|
||
|
||
override fun cancel() {
|
||
com.cncat.vpn.common.log.Log.d("tryButton REGISTER cancel")
|
||
dialogDoMainChoose?.dismiss()
|
||
dialogDoMainChoose=null
|
||
}
|
||
})
|
||
dialogDoMainChoose?.show()
|
||
}
|
||
} catch (e: Exception) {
|
||
e.printStackTrace()
|
||
}
|
||
// if (super.switchServer()) {//切换服务器并直接重试
|
||
//// doRegister()
|
||
// doRegisterByEncryption()
|
||
// } else {
|
||
// MaterialDialog(this@SplashActivity).show {
|
||
// message(text = initErrMsg)
|
||
// positiveButton(R.string.retry) {
|
||
//// doRegister()
|
||
// doRegisterByEncryption()
|
||
// }
|
||
// negativeButton(R.string.cancel) {
|
||
// it.dismiss()
|
||
// finish()
|
||
// }
|
||
// }
|
||
// }
|
||
}
|
||
|
||
HttpReqType.LOGIN -> {
|
||
MaterialDialog(this@SplashActivity).show {
|
||
message(text = initErrMsg)
|
||
positiveButton(R.string.confirm) {
|
||
val encryName = AESUtil.byteArrayToHexStr(
|
||
AESUtil.encrypt(username)
|
||
)
|
||
val encryPsw = AESUtil.byteArrayToHexStr(
|
||
AESUtil.encrypt(BZYConstants.defaultPassword)
|
||
)
|
||
splashAtyVM.login(encryName, encryPsw)
|
||
}
|
||
negativeButton(R.string.cancel) {
|
||
it.dismiss()
|
||
finish()
|
||
}
|
||
}
|
||
}
|
||
|
||
HttpReqType.CHECK_LOGIN -> {
|
||
com.cncat.vpn.common.log.Log.d("httpFailure HttpReqType.CHECK_LOGIN")
|
||
try {
|
||
RxToast.error("检测到网络异常,请尝试切换其他地址.")
|
||
SplashHelper(splashAtyVM).getHostWithFallback { success ->
|
||
MainScope().launch {
|
||
if (success) {
|
||
if (dialogDoMainChoose==null) {
|
||
dialogDoMainChoose = DialogDoMainChoose(this@SplashActivity)
|
||
}
|
||
if (dialogDoMainChoose?.isShowing==false){
|
||
dialogDoMainChoose?.setOnTryButtonListener(object :
|
||
DialogDoMainChoose.OnTryButtonListener {
|
||
override fun tryButton() {
|
||
var currentHost = MMKV.defaultMMKV()
|
||
.decodeString(BZYConstants.MMKV_KEY_CURRENT_HOST, "")
|
||
// com.cncat.vpn.common.log.Log.d("tryButton CHECK_LOGIN currentHost==>${currentHost}")
|
||
splashAtyVM.checkLogin()
|
||
}
|
||
|
||
override fun cancel() {
|
||
com.cncat.vpn.common.log.Log.d("tryButton CHECK_LOGIN cancel")
|
||
dialogDoMainChoose?.dismiss()
|
||
}
|
||
})
|
||
dialogDoMainChoose?.show()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
} catch (e: Exception) {
|
||
e.printStackTrace()
|
||
toLoginPage()
|
||
}
|
||
|
||
// if (super.switchServer()) {
|
||
// splashAtyVM.checkLogin()
|
||
// } else {
|
||
// toLoginPage()
|
||
// }
|
||
}
|
||
|
||
else -> {}
|
||
}
|
||
}
|
||
|
||
|
||
//申请权限
|
||
private fun checkPermissions(permissions: HashSet<String>): Boolean {
|
||
for (permission in permissions) {
|
||
val permissionStatus = ContextCompat.checkSelfPermission(this, permission)
|
||
if (permissionStatus == PackageManager.PERMISSION_DENIED)
|
||
deniedPermissions.add(permission)
|
||
else
|
||
deniedPermissions.remove(permission)
|
||
}
|
||
return deniedPermissions.isEmpty()
|
||
|
||
}
|
||
|
||
override fun onRequestPermissionsResult(
|
||
requestCode: Int,
|
||
permissions: Array<out String>,
|
||
grantResults: IntArray,
|
||
) {
|
||
|
||
Log.e("data", "onRequestPermissionsResult requestCode==> " + requestCode)
|
||
permissions.forEach {
|
||
Log.e("data", "onRequestPermissionsResult permissions ==> " + it)
|
||
}
|
||
grantResults.forEach {
|
||
Log.e("data", "onRequestPermissionsResult grantResults==> " + it)
|
||
}
|
||
|
||
|
||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||
//
|
||
val deniedAndNoLongerPromptPermissions = HashSet<String>()
|
||
if (requestCode == PERMISSION_REQUEST_CODE) {
|
||
for ((i, permission) in permissions.withIndex()) {
|
||
if (!ActivityCompat.shouldShowRequestPermissionRationale(
|
||
this,
|
||
permission
|
||
)
|
||
) //不在提示权限包含 已通过的和勾选不在提示的权限
|
||
if (grantResults[i] == 0)
|
||
deniedAndNoLongerPromptPermissions.remove(permission)
|
||
else
|
||
deniedAndNoLongerPromptPermissions.add(permission)
|
||
else
|
||
deniedAndNoLongerPromptPermissions.remove(permission)
|
||
}
|
||
}
|
||
if (deniedAndNoLongerPromptPermissions.isNotEmpty()) {
|
||
if (checkPermissions(mPermissions)) {
|
||
isNeedRegister() //TODO
|
||
return
|
||
}
|
||
val deniedAndNoLongerPromptPermissionsName = StringBuilder()
|
||
for (deniedAndNoLongerPromptPermission in deniedAndNoLongerPromptPermissions) {
|
||
when (deniedAndNoLongerPromptPermission) {
|
||
// Manifest.permission.WRITE_EXTERNAL_STORAGE -> {
|
||
// if (deniedPermissions.contains(deniedAndNoLongerPromptPermission))
|
||
// deniedAndNoLongerPromptPermissionsName.append("【存储】")
|
||
// else
|
||
// deniedAndNoLongerPromptPermissions.remove(
|
||
// deniedAndNoLongerPromptPermission
|
||
// )
|
||
// }
|
||
|
||
Manifest.permission.READ_PHONE_STATE -> {
|
||
if (deniedPermissions.contains(deniedAndNoLongerPromptPermission))
|
||
deniedAndNoLongerPromptPermissionsName.append("【手机信息】")
|
||
else
|
||
deniedAndNoLongerPromptPermissions.remove(
|
||
deniedAndNoLongerPromptPermission
|
||
)
|
||
}
|
||
|
||
Manifest.permission.ACCESS_WIFI_STATE -> {
|
||
if (deniedPermissions.contains(deniedAndNoLongerPromptPermission))
|
||
deniedAndNoLongerPromptPermissionsName.append("【访问WIFI信息】")
|
||
else
|
||
deniedAndNoLongerPromptPermissions.remove(
|
||
deniedAndNoLongerPromptPermission
|
||
)
|
||
}
|
||
}
|
||
}
|
||
val rxDialogSureCancel = RxDialogSureCancel(this)
|
||
rxDialogSureCancel.setContent("需要${deniedAndNoLongerPromptPermissionsName}权限,由于您设置了不再提示,需要手动开启权限!")
|
||
rxDialogSureCancel.setCancelListener {
|
||
rxDialogSureCancel.cancel()
|
||
finish()
|
||
}
|
||
rxDialogSureCancel.setSureListener {
|
||
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
|
||
val uri = Uri.fromParts("package", packageName, null)
|
||
intent.data = uri
|
||
startActivityForResult(intent, PERMISSION_SETTING_REQUEST_CODE)
|
||
}
|
||
rxDialogSureCancel.show()
|
||
Logger.i("${deniedAndNoLongerPromptPermissions.size}需要${deniedAndNoLongerPromptPermissionsName.toString()}权限,由于您设置了不再提示,需要手动开启权限!")
|
||
} else {
|
||
if (checkPermissions(mPermissions)) {
|
||
isNeedRegister() //TODO
|
||
} else {
|
||
finish()
|
||
}
|
||
}
|
||
}
|
||
|
||
@RequiresApi(Build.VERSION_CODES.M)
|
||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||
super.onActivityResult(requestCode, resultCode, data)
|
||
if (requestCode == PERMISSION_SETTING_REQUEST_CODE) {
|
||
if (checkPermissions(mPermissions)) {
|
||
isNeedRegister() //TODO
|
||
} else {
|
||
requestPermissions(deniedPermissions.toTypedArray(), PERMISSION_REQUEST_CODE)
|
||
}
|
||
}
|
||
}
|
||
|
||
private fun toMainPage() {
|
||
//监测版本是否需要更新
|
||
splashAtyVM.appCheck()
|
||
}
|
||
|
||
private fun toLoginPage() {
|
||
val intent = Intent(this, LoginActivity::class.java)
|
||
startActivity(intent)
|
||
finish()
|
||
}
|
||
|
||
fun updateLanguage(language: String, locale: Locale) {
|
||
MMKV.defaultMMKV().encode(BZYConstants.languageInfo, language)
|
||
val resources = this.resources
|
||
val metrics = resources.displayMetrics
|
||
val config = resources.configuration
|
||
config.locale = locale
|
||
resources.updateConfiguration(config, metrics)
|
||
}
|
||
private fun showUpdateDialog(url: String, illustrate: String, isForce: Boolean) {
|
||
if (TextUtils.isEmpty(url)) {
|
||
RxToast.error(resources.getString(R.string.downloadEmpty))
|
||
return
|
||
}
|
||
var notice = illustrate
|
||
if (TextUtils.isEmpty(illustrate)) {
|
||
notice = resources.getString(R.string.NewVersion)
|
||
}
|
||
var isDownloaded = false;
|
||
var isFinish = false
|
||
var downFilePath = ""
|
||
|
||
val dialog = DialogAppVersion(this,
|
||
notice,
|
||
url,
|
||
isForce,
|
||
object : DialogAppVersion.OnClickListener {
|
||
override fun ok(tv_down: TextView, pb_down: ProgressBar) {
|
||
if (isFinish) {
|
||
installApk(downFilePath)
|
||
return
|
||
}
|
||
if (isDownloaded) {
|
||
RxToast.info(resources.getString(R.string.downloading))
|
||
return
|
||
}
|
||
isDownloaded = true
|
||
splashAtyVM.downLoadFile(url, object : DownLoadListener {
|
||
@SuppressLint("SetTextI18n")
|
||
override fun loading(progress: Int) {
|
||
lifecycleScope.async {
|
||
pb_down.progress = progress
|
||
tv_down.text = resources.getString(R.string.download) + "$progress%"
|
||
}
|
||
}
|
||
|
||
override fun finish(path: String) {
|
||
com.cncat.vpn.common.log.Log.d("down finish path==>$path")
|
||
isFinish = true
|
||
downFilePath = path
|
||
installApk(path)
|
||
}
|
||
|
||
override fun error(msg: String) {
|
||
com.cncat.vpn.common.log.Log.d("down error msg==>$msg")
|
||
}
|
||
|
||
})
|
||
}
|
||
|
||
override fun cancel() {
|
||
val intent = Intent(this@SplashActivity, UIMainActivity::class.java)
|
||
startActivity(intent)
|
||
finish()
|
||
}
|
||
})
|
||
dialog.show()
|
||
}
|
||
fun installApk(filePath: String) {
|
||
val file = File(filePath)
|
||
val uri: Uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||
FileProvider.getUriForFile(this, "${applicationContext.packageName}.fileprovider", file)
|
||
} else {
|
||
Uri.fromFile(file)
|
||
}
|
||
|
||
val intent = Intent(Intent.ACTION_VIEW).apply {
|
||
setDataAndType(uri, "application/vnd.android.package-archive")
|
||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||
|
||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||
}
|
||
}
|
||
startActivity(intent)
|
||
}
|
||
} |