合并提交
This commit is contained in:
parent
93ead85629
commit
e474d6bd57
|
|
@ -25,7 +25,7 @@ dependencies {
|
|||
implementation(libs.rikkax.multiprocess)
|
||||
val commonAar = file("libs/common.aar")
|
||||
val coreAar = file("libs/core.aar")
|
||||
val hideawayEar = file("libs/hideapi.aar")
|
||||
val hideapiAar = file("libs/hideapi.aar")
|
||||
val serviceAar = file("libs/service.aar")
|
||||
val oss = file("libs/oss-android-sdk-2.9.19.aar")
|
||||
if (oss.exists()) {
|
||||
|
|
@ -45,8 +45,8 @@ dependencies {
|
|||
println("core.aar does not exist")
|
||||
}
|
||||
|
||||
if (hideawayEar.exists()) {
|
||||
implementation(files(hideawayEar))
|
||||
if (hideapiAar.exists()) {
|
||||
implementation(files(hideapiAar))
|
||||
} else {
|
||||
println("hideapi.aar does not exist")
|
||||
}
|
||||
|
|
@ -58,14 +58,18 @@ dependencies {
|
|||
|
||||
implementation(libs.kotlin.coroutine)
|
||||
implementation(libs.androidx.core)
|
||||
// implementation(libs.androidx.activity)
|
||||
// implementation(libs.androidx.fragment)
|
||||
implementation(libs.androidx.appcompat)
|
||||
implementation(libs.androidx.coordinator)
|
||||
implementation(libs.androidx.recyclerview)
|
||||
implementation(libs.google.material)
|
||||
|
||||
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.9.1")
|
||||
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.9.1")
|
||||
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.9.1")
|
||||
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.5.1")
|
||||
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1")
|
||||
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.5.1")
|
||||
|
||||
// https://mvnrepository.com/artifact/com.tencent/mmkv-static
|
||||
implementation("com.tencent:mmkv-static:1.2.10")
|
||||
|
||||
implementation ("com.jakewharton:process-phoenix:3.0.0")
|
||||
|
|
@ -78,13 +82,29 @@ dependencies {
|
|||
api("com.orhanobut:logger:2.2.0")
|
||||
api("com.google.code.gson:gson:2.10.1")
|
||||
api(platform("com.squareup.okhttp3:okhttp-bom:4.10.0"))
|
||||
|
||||
// define any required OkHttp artifacts without version
|
||||
api("com.squareup.okhttp3:okhttp")
|
||||
api("com.squareup.okhttp3:logging-interceptor")
|
||||
//// https://mvnrepository.com/artifact/com.google.code.gson/gson
|
||||
// api("com.google.code.gson:gson:2.10.1")
|
||||
api("org.yaml:snakeyaml:1.29")
|
||||
|
||||
// https://mvnrepository.com/artifact/com.alipay.sdk/alipaysdk-android
|
||||
implementation("com.alipay.sdk:alipaysdk-android:15.8.17")
|
||||
// https://mvnrepository.com/artifact/com.journeyapps/zxing-android-embedded
|
||||
// implementation("com.journeyapps:zxing-android-embedded:3.6.0")
|
||||
|
||||
// https://mvnrepository.com/artifact/com.google.zxing/core
|
||||
// implementation("com.google.zxing:core:3.5.3")
|
||||
implementation("com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4")
|
||||
// https://mvnrepository.com/artifact/com.airbnb.android/lottie
|
||||
implementation("com.airbnb.android:lottie:5.2.0")
|
||||
implementation("com.github.bumptech.glide:glide:4.16.0")
|
||||
// https://mvnrepository.com/artifact/com.github.bumptech.glide/glide
|
||||
implementation("com.github.bumptech.glide:glide:4.13.2")
|
||||
// implementation("com.luozm.captcha:captcha:1.1.2")
|
||||
// implementation("com.aliyun.dpa:oss-android-sdk:2.9.19")
|
||||
// implementation ("com.hihonor.mcs:ads-identifier:1.0.3.301")
|
||||
implementation("com.github.gzu-liyujiang:Android_CN_OAID:4.2.8") {
|
||||
exclude("com.hihonor.mcs", "ads-identifier")
|
||||
exclude("com.huawei.hms", "ads-identifier")
|
||||
|
|
@ -92,7 +112,9 @@ dependencies {
|
|||
//stripe 支付
|
||||
implementation("com.stripe:stripe-android:21.4.2")// 使用最新版本
|
||||
implementation("com.github.getActivity:XXPermissions:20.0")
|
||||
// 华为的最新版本广告标识服务SDK,参阅 https://developer.huawei.com/consumer/cn/doc/HMSCore-Guides/identifier-service-version-change-history-0000001050066927
|
||||
api ("com.huawei.hms:ads-identifier:3.4.62.300")
|
||||
// 荣耀的最新版本广告标识服务SDK,参阅 https://developer.hihonor.com/cn/kitdoc?kitId=11030&navigation=guides&docId=intergrate.md
|
||||
api ("com.hihonor.mcs:ads-identifier:1.0.2.301")
|
||||
implementation("com.android.installreferrer:installreferrer:2.2")// 使用最新版本
|
||||
|
||||
|
|
@ -108,7 +130,9 @@ task("downloadGeoFiles") {
|
|||
|
||||
val geoFilesUrls = mapOf(
|
||||
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb" to "geoip.metadb",
|
||||
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat" to "geosite.dat")
|
||||
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat" to "geosite.dat",
|
||||
// "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country.mmdb" to "country.mmdb",
|
||||
)
|
||||
|
||||
doLast {
|
||||
geoFilesUrls.forEach { (downloadUrl, outputFileName) ->
|
||||
|
|
@ -159,6 +183,9 @@ android {
|
|||
abiFilters.add("armeabi-v7a")
|
||||
}
|
||||
}
|
||||
// sourceSets.all {
|
||||
// jniLibs.srcDir("src/main/jniLibs")
|
||||
// }
|
||||
sourceSets.all {
|
||||
jniLibs.srcDir("src/main/jniLibs")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,6 +166,9 @@
|
|||
<activity android:name=".webview.BZYWebViewNormal"
|
||||
android:process=":background"
|
||||
/>
|
||||
<activity android:name=".webview.BZYWebViewKeFu"
|
||||
android:process=":background"
|
||||
/>
|
||||
<service android:name=".service.ConnectionService"/>
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ import android.widget.Toast
|
|||
import androidx.appcompat.widget.AppCompatImageView
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.observe
|
||||
import com.baidu.mobads.action.ActionType
|
||||
import com.baidu.mobads.action.BaiduAction
|
||||
import com.yingmao.clash.view.dialog.RxDialogShapeLoading
|
||||
|
||||
import com.tencent.mmkv.MMKV
|
||||
|
|
@ -146,9 +144,6 @@ class BandPhoneActivity : BaseActivity() {
|
|||
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_PH_TOKEN)
|
||||
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_TOKEN)
|
||||
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_CURRENT_NODE)
|
||||
|
||||
//百度埋点完成注册
|
||||
BaiduAction.logAction(ActionType.REGISTER)
|
||||
var intent=Intent(CommonUtils.getApp(), LoginActivity::class.java)
|
||||
|
||||
intent.putExtra(BZYConstants.EXTRA_Bind_Account,phoneNumber)
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ import com.cncat.vpn.service.remote.IRemoteService
|
|||
import com.yingmao.clash.act.NewMainActivity.Companion.clashBinder
|
||||
import com.yingmao.clash.act.NewMainActivity.Companion.profileBinder
|
||||
import com.yingmao.clash.act.NewMainActivity.Companion.subUrl
|
||||
import com.yingmao.clash.act.ProxyModeActivity.ProxyMode
|
||||
import com.yingmao.clash.app.MainApplication
|
||||
import com.yingmao.clash.fragment.NewAccFragment.Companion.CHECK_NODE_REQUEST_CODE
|
||||
import com.yingmao.clash.util.Utils
|
||||
|
|
@ -657,4 +656,7 @@ class ChangeNodeActivity : BaseActivity(), View.OnClickListener {
|
|||
intent.setPackage(this.packageName)
|
||||
)
|
||||
}
|
||||
enum class ProxyMode {
|
||||
PAC, GLOBAL, PACKAGE
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,606 +0,0 @@
|
|||
package com.yingmao.clash.act
|
||||
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.widget.AppCompatImageView
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter
|
||||
import com.cncat.vpn.common.constants.Intents
|
||||
import com.cncat.vpn.common.log.Log
|
||||
import com.cncat.vpn.service.model.Profile
|
||||
import com.cncat.vpn.service.remote.IProfileManager
|
||||
import com.cncat.vpn.service.remote.IRemoteService
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonParser
|
||||
import com.tencent.mmkv.MMKV
|
||||
import com.yingmao.clash.R
|
||||
import com.yingmao.clash.act.NewMainActivity.Companion.clashBinder
|
||||
import com.yingmao.clash.act.NewMainActivity.Companion.profileBinder
|
||||
import com.yingmao.clash.act.NewMainActivity.Companion.subUrl
|
||||
import com.yingmao.clash.app.MainApplication
|
||||
import com.yingmao.clash.base.BaseActivity
|
||||
import com.yingmao.clash.conf.BZYConstants
|
||||
import com.yingmao.clash.conf.Conf
|
||||
import com.yingmao.clash.entity.ClashNodebBean
|
||||
import com.yingmao.clash.fragment.NewAccFragment
|
||||
import com.yingmao.clash.fragment.NewAccFragment.Companion.CHECK_NODE_RESULT_CODE
|
||||
import com.yingmao.clash.remote.Resource
|
||||
import com.yingmao.clash.util.Utils
|
||||
import com.yingmao.clash.view.RxToast
|
||||
import com.yingmao.clash.view.adapter.NodeTzListAdapter
|
||||
import com.yingmao.clash.view.dialog.DialogDoMainChoose
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Semaphore
|
||||
import kotlinx.coroutines.sync.withPermit
|
||||
import java.util.Timer
|
||||
import java.util.TimerTask
|
||||
import java.util.UUID
|
||||
|
||||
class ChangeNodeTzActivity : BaseActivity(), View.OnClickListener {
|
||||
|
||||
companion object {
|
||||
private var currentNode: MutableList<ClashNodebBean> = mutableListOf()
|
||||
|
||||
// var clash: ClashManager? = null
|
||||
}
|
||||
|
||||
private lateinit var swipeLayout: SwipeRefreshLayout
|
||||
private lateinit var changeNodeVM: ChangeNodeVM
|
||||
private lateinit var nodeListRv: RecyclerView
|
||||
private var names: List<String>? = null
|
||||
private lateinit var aiBack: AppCompatImageView
|
||||
private var broadcastReceiver: BroadcastReceiver? = null
|
||||
private var cacheNodeStr: String? = ""
|
||||
|
||||
// private var checkedNode: ClashNodebBean? = null
|
||||
private var uuid: UUID? = null
|
||||
|
||||
private var testRuning = false
|
||||
// var cprofile: ProfileManager? = null
|
||||
// private var currentNode: Profile? = null
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_change_node)
|
||||
setMoreBar("线路测速", this)
|
||||
changeNodeVM = ViewModelProvider(this).get(ChangeNodeVM::class.java)
|
||||
initData()
|
||||
initViews()
|
||||
|
||||
// cprofile = ProfileManager(this)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
intent.putExtra(BZYConstants.EXTRA_KEY_IS_RUNING, is_runing)
|
||||
setResult(2, intent)
|
||||
super.onBackPressed()
|
||||
}
|
||||
|
||||
private fun initData() {
|
||||
// clash = MainApplication.getApp()?.let { ClashManager(it) }
|
||||
cacheNodeStr = MMKV.defaultMMKV().decodeString(BZYConstants.NODE_All_ITEM_NAME_KEY, "");
|
||||
|
||||
val intentFilter = IntentFilter(Intents.ACTION_NODE_LIST)
|
||||
broadcastReceiver = NodeListBR()
|
||||
if (Build.VERSION.SDK_INT >= 34 && applicationInfo.targetSdkVersion >= 34) {
|
||||
registerReceiver(
|
||||
broadcastReceiver,
|
||||
intentFilter,
|
||||
Context.RECEIVER_EXPORTED
|
||||
)
|
||||
} else {
|
||||
registerReceiver(
|
||||
broadcastReceiver,
|
||||
intentFilter
|
||||
)
|
||||
}
|
||||
// registerReceiver(
|
||||
// broadcastReceiver,
|
||||
// intentFilter
|
||||
// )
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun initViews() {
|
||||
aiBack = findViewById(R.id.aiBack)
|
||||
aiBack.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
swipeLayout = findViewById(R.id.swipeLayout)
|
||||
initRefreshLayout()
|
||||
nodeListRv = findViewById(R.id.rv_node_list)
|
||||
var userTrafficTv: TextView = findViewById(R.id.node_user_traffic)
|
||||
|
||||
findViewById<ImageView>(R.id.iv_back).setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
initAdapter()
|
||||
// Log.d("initViews cacheNodeStr==>${cacheNodeStr}")
|
||||
if (!TextUtils.isEmpty(cacheNodeStr)) {
|
||||
currentNode = getNodesInfo(cacheNodeStr!!)
|
||||
setNewData(currentNode)
|
||||
}
|
||||
|
||||
// if (!TextUtils.isEmpty(serStore.userTraffic)) {
|
||||
// userTrafficTv.visibility=View.VISIBLE
|
||||
// var jo = JsonParser.parseString(serStore.userTraffic).asJsonObject
|
||||
// var t = jo.get("total")
|
||||
// var d = jo.get("download").asLong
|
||||
// var u = jo.get("upload").asLong
|
||||
// val trafficUsedInGB = String.format("%.2f", (d + u) / 1024.0 / 1024.0 / 1024.0)
|
||||
// userTrafficTv.text="已用流量:${trafficUsedInGB}GB"
|
||||
// }
|
||||
}
|
||||
|
||||
private fun getNodesInfo(json: String): MutableList<ClashNodebBean> {
|
||||
var mList: MutableList<ClashNodebBean> = mutableListOf()
|
||||
if (TextUtils.isEmpty(json)) {
|
||||
return mList
|
||||
}
|
||||
val gson = Gson()
|
||||
var ja = JsonParser.parseString(json).asJsonArray
|
||||
|
||||
var cnb = ClashNodebBean("自动选择", "", "", 1, "", "", 0, true);
|
||||
mList.add(cnb)
|
||||
for (i in 0 until ja.size()) {
|
||||
var bean = gson.fromJson(ja.get(i).asString, ClashNodebBean::class.java)
|
||||
bean.delay = Utils.generateRandomTwoDigitNumber(10, 60)
|
||||
mList.add(bean)
|
||||
}
|
||||
return mList
|
||||
}
|
||||
|
||||
inner class NodeListBR : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
when (intent?.action) {
|
||||
Intents.ACTION_NODE_LIST -> {
|
||||
Log.d("ACTION_NODE_LIST ACTION_NODE_LIST")
|
||||
// val parcelableArrayListExtra = intent.getParcelableArrayListExtra<Map<String,Any>>("")
|
||||
hideLoading()
|
||||
// stopTimer()
|
||||
timerJob?.cancel()
|
||||
dialogDoMainChoose?.dismiss()
|
||||
// var json = intent.getStringExtra("node_list")
|
||||
// Log.d("onReceive: $json")
|
||||
// currNodeJsonA = json
|
||||
var json = serStore.nodes
|
||||
// Log.d("serStore.nodes: $json")
|
||||
if (TextUtils.isEmpty(json)) {
|
||||
return
|
||||
}
|
||||
//缓存订阅地址
|
||||
subUrl = nowSubUrl
|
||||
MMKV.defaultMMKV().encode(BZYConstants.PROFILE_SUB_URL, nowSubUrl)
|
||||
//缓存节点
|
||||
MMKV.defaultMMKV().encode(BZYConstants.NODE_All_ITEM_NAME_KEY, json)
|
||||
currentNode = getNodesInfo(json)
|
||||
// val listType = object : TypeToken<MutableList<ClashNodebBean>>() {}.type
|
||||
// currentNode = gson.fromJson(json, listType)
|
||||
setNewData(currentNode)
|
||||
swipeLayout.isRefreshing = false
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
broadcastReceiver?.let {
|
||||
unregisterReceiver(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
// uuid = intent.getStringExtra(BZYConstants.MMKV_KEY_CURRENT_NODE)
|
||||
// com.cncat.vpn.common.log.Log.d("ChangeNode uuid==>$uuid")
|
||||
is_runing = intent.getBooleanExtra(BZYConstants.EXTRA_KEY_IS_RUNING, false)
|
||||
}
|
||||
|
||||
val remote = Resource<IRemoteService>()
|
||||
var GetNodeTimeOutNum = 5;
|
||||
var is_runing = false
|
||||
private var timer: Timer? = null
|
||||
private var timerTask: TimerTask? = null
|
||||
var nowSubUrl: String = ""
|
||||
private fun updateProfile(isDelete: Boolean) {
|
||||
// showLoading("正在获取...", this@ChangeNodeActivity)
|
||||
|
||||
try {
|
||||
|
||||
|
||||
launch(Dispatchers.IO) {
|
||||
profileBinder?.let { profileManager ->
|
||||
var mProfile = profileManager.queryAll().find {
|
||||
it.name == Conf.getClashConfName(this@ChangeNodeTzActivity.applicationContext)
|
||||
}
|
||||
|
||||
if (mProfile == null) {
|
||||
//为空的情况下选择第一个
|
||||
profileManager.queryAll().forEach { profile ->
|
||||
mProfile = profile
|
||||
return@forEach
|
||||
}
|
||||
}
|
||||
|
||||
mProfile?.let { profile ->
|
||||
uuid = profile.uuid
|
||||
Log.d("ChangeNode22 uuid==>${profile.uuid}")
|
||||
if (isDelete) {
|
||||
Log.d("gogogogogo isDelete")
|
||||
profileManager.delete(profile.uuid)
|
||||
MMKV.defaultMMKV()
|
||||
.removeValueForKey(BZYConstants.NODE_All_ITEM_NAME_KEY)
|
||||
setSub2(profileManager, nowSubUrl)
|
||||
} else {
|
||||
Log.d("gogogogogo update")
|
||||
profileManager.setActive(profile)
|
||||
delay(500)
|
||||
if (!TextUtils.isEmpty(profile.source)) {
|
||||
// Log.d("updateProfile pro.source==>${profile.source}, url==>${nowSubUrl}")
|
||||
if (profile.source != nowSubUrl) {
|
||||
Log.d("updateProfile patch")
|
||||
profileManager.patch(
|
||||
profile.uuid,
|
||||
profile.name,
|
||||
nowSubUrl,
|
||||
1800000L
|
||||
)
|
||||
Log.d("updateProfile patch 1")
|
||||
profileManager.commit(profile.uuid) { status ->
|
||||
Log.d("updateProfile updateStatus: " + Gson().toJson(status.args) + ", pro==>" + status.progress)
|
||||
}
|
||||
Log.d("updateProfile patch 2")
|
||||
}
|
||||
}
|
||||
Log.d("updateProfile go update")
|
||||
profileManager.update(profile.uuid)
|
||||
}
|
||||
Log.d("gogogogogo end")
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun initRefreshLayout() {
|
||||
swipeLayout.setColorSchemeColors(Color.rgb(47, 223, 189))
|
||||
swipeLayout.setOnRefreshListener(object : OnRefreshListener {
|
||||
override fun onRefresh() {
|
||||
if (testRuning) {
|
||||
RxToast.info("正在测速中.");
|
||||
swipeLayout.isRefreshing = false
|
||||
return
|
||||
}
|
||||
com.cncat.vpn.common.log.Log.d("onRefresh")
|
||||
// getNodesStatus();
|
||||
// changeNodeVM.getAirNodes()
|
||||
swipeLayout.isRefreshing = true
|
||||
updateProfile(false)
|
||||
com.cncat.vpn.common.log.Log.d("onRefresh end")
|
||||
swipeLayout.isRefreshing = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
subUrl?.let {
|
||||
nowSubUrl = it
|
||||
}
|
||||
doProfile()
|
||||
|
||||
}
|
||||
|
||||
fun doProfile() {
|
||||
if (TextUtils.isEmpty(cacheNodeStr)) {
|
||||
|
||||
}
|
||||
showLoading("正在获取...", this@ChangeNodeTzActivity)
|
||||
startTimer()
|
||||
updateProfile(false)
|
||||
|
||||
}
|
||||
|
||||
private fun changeSubUrl(originalUrl: String, newUrl: String) {
|
||||
if(!originalUrl.isNullOrEmpty()&&!newUrl.isNullOrEmpty()){
|
||||
nowSubUrl = originalUrl.replace(Regex("https://[^/]+/"), "$newUrl/")
|
||||
MMKV.defaultMMKV().encode(BZYConstants.PROFILE_SUB_URL, nowSubUrl)
|
||||
}
|
||||
}
|
||||
|
||||
val reloadLock = Semaphore(10)
|
||||
private fun setPing() {
|
||||
if (!NewAccFragment.clashRunning) {
|
||||
RxToast.info("请先开启加速后,再进行测试.");
|
||||
return
|
||||
}
|
||||
if (testRuning) {
|
||||
RxToast.info("正在测速中.");
|
||||
return
|
||||
}
|
||||
testRuning = true
|
||||
updateMoreBar("测速中")
|
||||
launch(Dispatchers.IO) {
|
||||
var group = reloadLock.withPermit {
|
||||
clashBinder?.let { cb ->
|
||||
var names = cb.queryProxyGroupNames(false)
|
||||
if (names.isNotEmpty()) {
|
||||
cb.healthCheck(names[0])
|
||||
}
|
||||
delay(1000)
|
||||
cb.queryProxyGroup(names[0], uiStore.proxySort);
|
||||
}
|
||||
}
|
||||
testRuning = false
|
||||
runOnUiThread { updateMoreBar("线路测速") }
|
||||
var newDatas = mutableListOf<ClashNodebBean>();
|
||||
group?.proxies?.forEach { proxy ->
|
||||
Log.d("node==>${proxy}")
|
||||
if (currentNode?.isNotEmpty() == true) {
|
||||
for (nodeItem: ClashNodebBean in currentNode!!) {
|
||||
if (nodeItem.name == proxy.name) {
|
||||
if (proxy.name != "自动选择") {
|
||||
nodeItem.delay = proxy.delay;
|
||||
}
|
||||
Log.d("nodeItem==>${nodeItem}")
|
||||
newDatas.add(nodeItem)
|
||||
return@forEach
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (newDatas.isNotEmpty()) {
|
||||
setNewData(newDatas)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun setNewData(nodes: MutableList<ClashNodebBean>?) {
|
||||
runOnUiThread {
|
||||
if (nodes != null) {
|
||||
nodeListAdapter.setNewInstance(nodes)
|
||||
var selected_name =
|
||||
MMKV.defaultMMKV().decodeString(BZYConstants.NODE_SELECTED_NAME_KEY, "");
|
||||
for ((index, node) in nodes.withIndex()) {
|
||||
if (node.name == selected_name) {
|
||||
nodeListAdapter.selectedPosition = index
|
||||
// checkedNode = node
|
||||
}
|
||||
}
|
||||
nodeListAdapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var nodeListAdapter: NodeTzListAdapter = NodeTzListAdapter(R.layout.node_tz_list_item_layout)
|
||||
private fun initAdapter() {
|
||||
nodeListRv.layoutManager = LinearLayoutManager(this)
|
||||
nodeListRv.adapter = nodeListAdapter
|
||||
nodeListAdapter.selectedPosition
|
||||
nodeListAdapter.setOnItemClickListener { baseQuickAdapter: BaseQuickAdapter<*, *>, view: View, position: Int ->
|
||||
(baseQuickAdapter.getItem(position) as ClashNodebBean).let { profile ->
|
||||
com.cncat.vpn.common.log.Log.i("select_node : ${profile.name}")
|
||||
// checkedNode = profile
|
||||
MMKV.defaultMMKV().encode(BZYConstants.NODE_SELECTED_NAME_KEY, profile.name)
|
||||
nodeListAdapter.notifyItemChanged(nodeListAdapter.selectedPosition)
|
||||
nodeListAdapter.selectedPosition =
|
||||
if (nodeListAdapter.selectedPosition == position) -1 else position
|
||||
nodeListAdapter.notifyItemChanged(position)
|
||||
// launch {
|
||||
// withClash {
|
||||
// val names = queryProxyGroupNames(false)
|
||||
// val mode = queryOverride(Clash.OverrideSlot.Session).mode
|
||||
// com.cncat.vpn.common.log.Log.d("names 222==>${names}, mode==>$mode")
|
||||
// names?.let { ns ->
|
||||
// if (ns.isNotEmpty()) {
|
||||
// patchSelector(ns[0], profile.name)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
launch(Dispatchers.IO) {
|
||||
val intent = Intent()
|
||||
intent.putExtra(BZYConstants.MMKV_KEY_SELECT_NODE_NAME, "自动选择")
|
||||
intent.putExtra(BZYConstants.EXTRA_KEY_IS_RUNING, is_runing)
|
||||
setResult(CHECK_NODE_RESULT_CODE, intent)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createProfile() {
|
||||
launch(Dispatchers.IO) {
|
||||
profileBinder?.let { pro ->
|
||||
uuid?.let { uu ->
|
||||
pro.delete(uu)
|
||||
delay(500)
|
||||
setSub2(pro, subUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public suspend fun setSub2(pm: IProfileManager, url: String?) {
|
||||
// com.cncat.vpn.common.log.Log.d("setSub2.... url==>$url")
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
com.cncat.vpn.common.log.Log.d("setSub2 url isEmpty")
|
||||
return
|
||||
}
|
||||
|
||||
com.cncat.vpn.common.log.Log.d("setSub2 2")
|
||||
|
||||
|
||||
com.cncat.vpn.common.log.Log.d("setSub2 3")
|
||||
val pro = pm.queryAll().find {
|
||||
it.name == Conf.getClashConfName(this@ChangeNodeTzActivity.applicationContext)
|
||||
}
|
||||
com.cncat.vpn.common.log.Log.d("setSub2 4")
|
||||
pro?.let {
|
||||
com.cncat.vpn.common.log.Log.d("setSub2 pro 已存在 ==>")
|
||||
// pm.setActive(it)
|
||||
|
||||
com.cncat.vpn.common.log.Log.d("setSub2 setActive end")
|
||||
} ?: run {
|
||||
var uuid: UUID = pm.create(
|
||||
Profile.Type.Url,
|
||||
Conf.getClashConfName(this@ChangeNodeTzActivity.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",
|
||||
url!!,
|
||||
1800000L
|
||||
)
|
||||
// coroutineScope {
|
||||
pm.commit(qPro.uuid) { status ->
|
||||
android.util.Log.d(
|
||||
Conf.TAG,
|
||||
"new updateStatus: " + Gson().toJson(status.args) + ", pro==>" + status.progress
|
||||
)
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var isCreate: Boolean = false
|
||||
private var timerJob: Job? = null
|
||||
private fun startTimer() {
|
||||
GetNodeTimeOutNum = 15
|
||||
timerJob = launch {
|
||||
repeat(16) {
|
||||
Log.d("GetNodeTimeOutNum==>$GetNodeTimeOutNum")
|
||||
if (GetNodeTimeOutNum == 0) {
|
||||
hideLoading()
|
||||
Log.d("stopTimer...")
|
||||
RxToast.error("获取节点失败...请尝试切换其他地址")
|
||||
showDomainList()
|
||||
timerJob?.cancel()
|
||||
// delay(1000)
|
||||
// this@ChangeNodeActivity.finish()
|
||||
|
||||
}
|
||||
GetNodeTimeOutNum--
|
||||
delay(1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var dialogDoMainChoose: DialogDoMainChoose? = null
|
||||
private fun showDomainList() {
|
||||
try {
|
||||
SplashHelper(changeNodeVM).getHostWithFallback { success ->
|
||||
MainScope().launch {
|
||||
|
||||
if (success) {
|
||||
if (dialogDoMainChoose == null) {
|
||||
dialogDoMainChoose = DialogDoMainChoose(this@ChangeNodeTzActivity)
|
||||
}
|
||||
if (dialogDoMainChoose?.isShowing == false) {
|
||||
dialogDoMainChoose?.setOnTryButtonListener(object :
|
||||
DialogDoMainChoose.OnTryButtonListener {
|
||||
override fun tryButton() {
|
||||
saveSubUrl()
|
||||
doProfile()
|
||||
dialogDoMainChoose?.dismiss()
|
||||
}
|
||||
|
||||
override fun cancel() {
|
||||
com.cncat.vpn.common.log.Log.d("tryButton CHECK_LOGIN cancel")
|
||||
|
||||
dialogDoMainChoose?.dismiss()
|
||||
}
|
||||
})
|
||||
dialogDoMainChoose?.setOnListItemListener(object :
|
||||
DialogDoMainChoose.OnListItemListener {
|
||||
override fun listItemClick() {
|
||||
saveSubUrl()
|
||||
MainApplication.restartApp(this@ChangeNodeTzActivity, object :
|
||||
MainApplication.OnRestartButtonListener {
|
||||
|
||||
override fun enterButton() {
|
||||
|
||||
}
|
||||
|
||||
override fun cancelButton() {
|
||||
doProfile()
|
||||
dialogDoMainChoose?.dismiss()
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
})
|
||||
dialogDoMainChoose?.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveSubUrl() {
|
||||
var currentHost = MMKV.defaultMMKV()
|
||||
.decodeString(BZYConstants.MMKV_KEY_CURRENT_HOST, "")
|
||||
// com.cncat.vpn.common.log.Log.d("tryButton currentHost==>${currentHost}")
|
||||
var oldUrl = nowSubUrl
|
||||
currentHost?.let { changeSubUrl(oldUrl, it) }
|
||||
}
|
||||
|
||||
private fun stopTimer() {
|
||||
timerTask?.cancel()
|
||||
timer?.purge()
|
||||
timer?.cancel()
|
||||
timerTask = null
|
||||
timer = null
|
||||
}
|
||||
|
||||
override fun onClick(p0: View?) {
|
||||
when (p0?.id) {
|
||||
R.id.tv_more -> {
|
||||
setPing()
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ import com.yingmao.clash.net.http.HttpReqType
|
|||
import com.yingmao.clash.net.http.NetService
|
||||
|
||||
class ExpensesRecordVM: BaseViewMode() {
|
||||
fun getExpensesRecord(page :PageInfo){
|
||||
fun getExpensesRecord(page : ExpensesRecordActivity.PageInfo){
|
||||
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,"")!!
|
||||
|
|
|
|||
|
|
@ -79,6 +79,8 @@ 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 kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.Job
|
||||
|
|
@ -776,7 +778,7 @@ class NewMainActivity : BaseActivity() {
|
|||
)
|
||||
}
|
||||
|
||||
private fun goCheckLogin() {
|
||||
fun goCheckLogin() {
|
||||
mainAtyVM.checkLogin()
|
||||
}
|
||||
private fun showBindAccount() {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@ package com.yingmao.clash.base
|
|||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.content.res.Configuration
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.NetworkCapabilities
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
|
|
@ -14,14 +18,24 @@ import android.view.inputmethod.InputMethodManager
|
|||
import android.widget.*
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.collection.arraySetOf
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.orhanobut.logger.Logger
|
||||
import com.tencent.mmkv.MMKV
|
||||
import com.yingmao.clash.BuildConfig
|
||||
import com.yingmao.clash.R
|
||||
import com.yingmao.clash.conf.BZYConstants
|
||||
import com.yingmao.clash.conf.Conf
|
||||
import com.cncat.vpn.core.bridge.ClashException
|
||||
import com.cncat.vpn.core.model.TunnelState
|
||||
//import com.yingmao.clash.design.model.DarkMode
|
||||
//import com.yingmao.clash.design.store.UiStore
|
||||
//import com.yingmao.clash.design.ui.DayNight
|
||||
import com.yingmao.clash.net.http.HttpStatus
|
||||
import com.yingmao.clash.remote.Broadcasts
|
||||
import com.yingmao.clash.remote.Remote
|
||||
import com.cncat.vpn.service.store.ServiceStore
|
||||
import com.yingmao.clash.util.ApplicationObserver
|
||||
import com.yingmao.clash.util.StatusBarUtils
|
||||
import com.yingmao.clash.util.UiStore
|
||||
import com.yingmao.clash.view.dialog.RxDialogShapeLoading
|
||||
|
|
@ -29,26 +43,59 @@ import kotlinx.coroutines.CoroutineScope
|
|||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
open class BaseActivity : AppCompatActivity(), CoroutineScope by MainScope(), Broadcasts.Observer {
|
||||
lateinit var titleBar: RelativeLayout
|
||||
lateinit var backIv: ImageView
|
||||
lateinit var title: TextView
|
||||
lateinit var more_tv: TextView
|
||||
protected val uiStore by lazy { UiStore(this) }
|
||||
protected val events = Channel<Event>(Channel.UNLIMITED)
|
||||
private var baseLoading: RxDialogShapeLoading? = null
|
||||
|
||||
// private var dayNight: DayNight = DayNight.Day
|
||||
var baseLoading: RxDialogShapeLoading? = null
|
||||
val serStore by lazy { ServiceStore(this) }
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.M)
|
||||
companion object {
|
||||
// var switchFinshSet: MutableSet<String>? = null
|
||||
}
|
||||
|
||||
sealed class RequestTunnel {
|
||||
object ReloadAll : RequestTunnel()
|
||||
object ReLaunch : RequestTunnel()
|
||||
|
||||
data class PatchMode(val mode: TunnelState.Mode?) : RequestTunnel()
|
||||
data class Reload(val index: Int) : RequestTunnel()
|
||||
data class Select(val index: Int, val name: String) : RequestTunnel()
|
||||
data class UrlTest(val index: Int) : RequestTunnel()
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; //竖屏
|
||||
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; //竖屏
|
||||
StatusBarUtils.with(this).init()
|
||||
window.decorView.systemUiVisibility =
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
||||
}
|
||||
|
||||
|
||||
override fun setContentView(layoutResID: Int) {
|
||||
val baseView = View.inflate(this, R.layout.activity_base, null)
|
||||
titleBar = baseView.findViewById(R.id.rl_title_bar)
|
||||
backIv = baseView.findViewById(R.id.iv_back)
|
||||
title = baseView.findViewById(R.id.tv_title)
|
||||
more_tv = baseView.findViewById(R.id.tv_more)
|
||||
val container = baseView.findViewById<FrameLayout>(R.id.fl_container)
|
||||
val params = FrameLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.MATCH_PARENT,
|
||||
FrameLayout.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
val view = View.inflate(this, layoutResID, null)
|
||||
container.addView(view, params)
|
||||
super.setContentView(baseView)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
|
@ -67,6 +114,33 @@ open class BaseActivity : AppCompatActivity(), CoroutineScope by MainScope(), Br
|
|||
cancel()
|
||||
}
|
||||
|
||||
fun showTitleBar(titleText: String) {
|
||||
titleBar.visibility = View.VISIBLE
|
||||
title.text = titleText
|
||||
backIv.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
fun showTitleBar(titleText: String, intent: Intent) {
|
||||
titleBar.visibility = View.VISIBLE
|
||||
title.text = titleText
|
||||
backIv.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
fun setMoreBar(moreInfo: String, listener: View.OnClickListener) {
|
||||
more_tv.visibility = View.VISIBLE
|
||||
more_tv.text = moreInfo
|
||||
more_tv.setOnClickListener(listener)
|
||||
}
|
||||
|
||||
fun updateMoreBar(moreInfo: String) {
|
||||
more_tv.text = moreInfo
|
||||
}
|
||||
|
||||
|
||||
open fun observe(activity: BaseActivity, viewMode: BaseViewMode) {
|
||||
viewMode.statusData.observe(activity) {
|
||||
when (it) {
|
||||
|
|
@ -93,14 +167,16 @@ open class BaseActivity : AppCompatActivity(), CoroutineScope by MainScope(), Br
|
|||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
open fun setupUI(view: View) {
|
||||
// Set up touch listener for non-text box views to hide keyboard.
|
||||
if (view !is EditText) view.setOnTouchListener { _, _ ->
|
||||
hideSoftKeyboard(this@BaseActivity)
|
||||
false
|
||||
}
|
||||
|
||||
//If a layout container, iterate over children and seed recursion.
|
||||
if (view is ViewGroup) {
|
||||
for (i in 0 until view.childCount) {
|
||||
val innerView: View = view.getChildAt(i)
|
||||
for (i in 0 until (view as ViewGroup).childCount) {
|
||||
val innerView: View = (view as ViewGroup).getChildAt(i)
|
||||
setupUI(innerView)
|
||||
}
|
||||
}
|
||||
|
|
@ -114,6 +190,24 @@ open class BaseActivity : AppCompatActivity(), CoroutineScope by MainScope(), Br
|
|||
activity.currentFocus!!.windowToken, 0
|
||||
)
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||
super.onConfigurationChanged(newConfig)
|
||||
// if (queryDayNight(newConfig) != dayNight) {
|
||||
// ApplicationObserver.createdActivities.forEach {
|
||||
// it.recreate()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// private fun queryDayNight(config: Configuration = resources.configuration): DayNight {
|
||||
// return when (uiStore.darkMode) {
|
||||
// DarkMode.Auto -> if (config.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES) DayNight.Night else DayNight.Day
|
||||
// DarkMode.ForceLight -> DayNight.Day
|
||||
// DarkMode.ForceDark -> DayNight.Night
|
||||
// }
|
||||
// }
|
||||
|
||||
override fun onProfileChanged() {
|
||||
events.trySend(Event.ProfileChanged)
|
||||
}
|
||||
|
|
@ -140,6 +234,12 @@ open class BaseActivity : AppCompatActivity(), CoroutineScope by MainScope(), Br
|
|||
|
||||
override fun onStopped(cause: String?) {
|
||||
events.trySend(Event.ClashStop)
|
||||
|
||||
// if (cause != null && activityStarted) {
|
||||
// launch {
|
||||
// design?.showExceptionToast(ClashException(cause))
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
enum class Event {
|
||||
|
|
@ -170,6 +270,63 @@ open class BaseActivity : AppCompatActivity(), CoroutineScope by MainScope(), Br
|
|||
baseLoading?.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
fun selectServer() {
|
||||
val mmkv = MMKV.defaultMMKV()
|
||||
val routerHost = mmkv.decodeStringSet(BZYConstants.MMKV_KEY_ROUTER_HOST, HashSet())
|
||||
}
|
||||
|
||||
@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
|
||||
}
|
||||
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.M)
|
||||
fun isNetworkAvailable(context: Context): Boolean {
|
||||
val connectivityManager =
|
||||
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
|
||||
val network = connectivityManager.activeNetwork ?: return false
|
||||
val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
|
||||
|
||||
return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun switchServer2(): Boolean {
|
||||
var isChange = false
|
||||
|
|
@ -178,38 +335,71 @@ open class BaseActivity : AppCompatActivity(), CoroutineScope by MainScope(), Br
|
|||
mmkv.decodeString(BZYConstants.MMKV_KEY_CURRENT_HOST, BuildConfig.service_url)
|
||||
var newUrlString = originalUrl
|
||||
val routerHost = mmkv.decodeStringSet(BZYConstants.MMKV_KEY_ROUTER_HOST, HashSet())
|
||||
val switchFinishSet = mmkv.decodeStringSet(BZYConstants.MMKV_KEY_Switch_Finsh_Set, HashSet())
|
||||
var switchFinshSet = mmkv.decodeStringSet(BZYConstants.MMKV_KEY_Switch_Finsh_Set, HashSet())
|
||||
routerHost?.let {
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
// if (!isNetworkAvailable(this@BaseActivity)){
|
||||
// return isChange
|
||||
// }
|
||||
// }
|
||||
if (it.isEmpty()) {
|
||||
Log.d(Conf.TAG, "routerHost isEmpty")
|
||||
return false
|
||||
return isChange
|
||||
}
|
||||
com.cncat.vpn.common.log.Log.d("switchFinshSet.size==>${switchFinishSet?.size!!} , routerHost.size==>${routerHost.size}")
|
||||
com.cncat.vpn.common.log.Log.d("switchFinshSet.size==>${switchFinshSet?.size!!} , routerHost.size==>${routerHost.size}")
|
||||
//次数已满
|
||||
if (switchFinishSet.size >= routerHost.size) {
|
||||
return false
|
||||
if (switchFinshSet?.size!! >= routerHost.size) {
|
||||
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, contains==>${switchFinshSet?.contains(newUrl)}"
|
||||
// )
|
||||
// if (newUrl == originalUrl) {
|
||||
// switchFinshSet?.add(newUrl)
|
||||
// iterator.remove()
|
||||
// continue
|
||||
// }
|
||||
// if (switchFinshSet?.contains(newUrl) == true) {
|
||||
// iterator.remove()
|
||||
// } else {
|
||||
// Log.e("Retry", "切换到新url:$newUrl")
|
||||
// isChange = true
|
||||
// newUrlString = newUrl
|
||||
// iterator.remove()
|
||||
// if (originalUrl != null) {
|
||||
// switchFinshSet?.add(originalUrl)
|
||||
// mmkv.encode(BZYConstants.MMKV_KEY_OLD_CURRENT_HOST, originalUrl)
|
||||
// }
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
for (url in it) {
|
||||
|
||||
if (url == originalUrl) {
|
||||
switchFinishSet.add(url)
|
||||
mmkv.encode(BZYConstants.MMKV_KEY_Switch_Finsh_Set, switchFinishSet)
|
||||
switchFinshSet?.add(url)
|
||||
mmkv.encode(BZYConstants.MMKV_KEY_Switch_Finsh_Set, switchFinshSet)
|
||||
continue
|
||||
}
|
||||
|
||||
if (switchFinishSet.contains(url)) {
|
||||
if (switchFinshSet?.contains(url) == true) {
|
||||
continue
|
||||
} else {
|
||||
isChange = true
|
||||
Log.e("Retry", "切换到新url:$url")
|
||||
android.util.Log.e("Retry", "切换到新url:$url")
|
||||
newUrlString = url
|
||||
switchFinishSet.add(newUrlString)
|
||||
mmkv.encode(BZYConstants.MMKV_KEY_Switch_Finsh_Set, switchFinishSet)
|
||||
switchFinshSet?.add(newUrlString)
|
||||
mmkv.encode(BZYConstants.MMKV_KEY_Switch_Finsh_Set, switchFinshSet)
|
||||
// mmkv.encode(BZYConstants.MMKV_KEY_OLD_CURRENT_HOST, newUrlString)
|
||||
break
|
||||
}
|
||||
}
|
||||
// mmkv.encode(BZYConstants.MMKV_KEY_ROUTER_HOST, routerHost)
|
||||
mmkv.encode(BZYConstants.MMKV_KEY_CURRENT_HOST, newUrlString)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class Conf {
|
|||
return context?.getString(R.string.app_name_taizi)!!
|
||||
} else {
|
||||
if (BuildConfig.is_ym) {
|
||||
return context?.getString(R.string.WFApiPort)!!
|
||||
return context?.getString(R.string.app_name_gz)!!
|
||||
} else {
|
||||
return context?.getString(R.string.app_name)!!
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ import com.yingmao.clash.R
|
|||
import com.yingmao.clash.act.NewMainActivity
|
||||
import com.yingmao.clash.act.NewMainActivity.Companion.isSubed
|
||||
import com.yingmao.clash.act.NewMainActivity.Companion.newUuid
|
||||
import com.yingmao.clash.act.ProxyModeActivity
|
||||
import com.yingmao.clash.act.NewMainActivity.Companion.profileBinder
|
||||
import com.yingmao.clash.conf.BZYConstants
|
||||
import com.yingmao.clash.conf.Conf
|
||||
import com.yingmao.clash.entity.ClashNodebBean
|
||||
|
|
@ -43,6 +43,7 @@ import com.yingmao.clash.net.http.entity.AppStartupStatus
|
|||
import com.yingmao.clash.service.ConnectionService
|
||||
import com.yingmao.clash.util.ActivityResultLifecycle
|
||||
import com.yingmao.clash.util.CommonUtils
|
||||
import com.yingmao.clash.util.Utils
|
||||
import com.yingmao.clash.util.startClashService
|
||||
import com.yingmao.clash.util.stopClashService
|
||||
import com.yingmao.clash.view.RxToast
|
||||
|
|
@ -89,7 +90,7 @@ class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
|
|||
// var currentNode: Profile? = null
|
||||
private var reConnection = false
|
||||
private var connectId=-1
|
||||
|
||||
private var baseLoading: RxDialogShapeLoading? = null
|
||||
override fun init(
|
||||
titleBarRl: RelativeLayout,
|
||||
backIv: ImageView,
|
||||
|
|
@ -182,7 +183,7 @@ class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
|
|||
rxDialogSureCancel.show()
|
||||
|
||||
} else {
|
||||
startClash()
|
||||
startClash(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -220,25 +221,21 @@ class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
|
|||
}
|
||||
|
||||
|
||||
private fun startClash() {
|
||||
if (checkExpire()) {
|
||||
if (isAdded) {
|
||||
RxToast.info(resources.getString(R.string.AccountExpired))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
private fun startClash(isStart:Boolean) {
|
||||
launch {
|
||||
NewMainActivity.profileBinder?.let { pm ->
|
||||
if(isStart){
|
||||
delay(2000)
|
||||
}
|
||||
profileBinder?.let { pm ->
|
||||
val active = pm.queryActive()
|
||||
if (active == null) {
|
||||
com.cncat.vpn.common.log.Log.d("startClash: 未选择")
|
||||
Log.d("startClash: 未选择")
|
||||
val pro = pm.queryAll().find {
|
||||
it.name == Conf.getClashConfName(this@NewAccFragment.context)
|
||||
}
|
||||
|
||||
pro?.let { profile ->
|
||||
com.cncat.vpn.common.log.Log.d("new setactive name " + profile.name)
|
||||
Log.d("new setactive name " + profile.name)
|
||||
pm.setActive(profile)
|
||||
|
||||
newUuid = profile.uuid.toString();
|
||||
|
|
@ -267,7 +264,6 @@ class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
|
|||
stateChanged(Clash_Starting, true)
|
||||
context?.startClashService()
|
||||
accelerateViewModel.appStartupStatus()
|
||||
// clashRunning = true
|
||||
}
|
||||
launch(Dispatchers.Main){
|
||||
lottieView.playAnimation()
|
||||
|
|
@ -285,6 +281,9 @@ class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
|
|||
stop_u_timer()
|
||||
e.printStackTrace()
|
||||
}
|
||||
withContext(Dispatchers.Main){
|
||||
hideLoading()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -340,7 +339,7 @@ class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
|
|||
|
||||
Intents.ACTION_CLASH_REQUEST_STOP -> {
|
||||
// clashRunning = false
|
||||
com.cncat.vpn.common.log.Log.d("ACTION_CLASH_REQUEST_STOP")
|
||||
Log.d("ACTION_CLASH_REQUEST_STOP")
|
||||
if (::rxDialogShapeLoading.isInitialized) {
|
||||
if (!rxDialogShapeLoading.isShowing) {
|
||||
if (isAdded) {
|
||||
|
|
@ -431,7 +430,7 @@ class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
|
|||
if (clashRunning) {
|
||||
Log.d("clashRunning $clashRunning")
|
||||
} else {
|
||||
startClash()
|
||||
startClash(false)
|
||||
}
|
||||
} else {
|
||||
if (::rxDialogShapeLoading.isInitialized || rxDialogShapeLoading.isShowing) {
|
||||
|
|
@ -452,9 +451,7 @@ class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
|
|||
checkGlo()
|
||||
}?.run {
|
||||
if (is_runing == true && !clashRunning) {
|
||||
startClash()
|
||||
} else {
|
||||
|
||||
startClash(false)
|
||||
}
|
||||
}
|
||||
} else if (requestCode == Proxy_Mode_REQUEST_CODE) {
|
||||
|
|
@ -528,7 +525,7 @@ class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
|
|||
val validPeriod = MMKV.defaultMMKV().decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD)
|
||||
if (validPeriod > 0) {
|
||||
var nowTime = System.currentTimeMillis();
|
||||
com.cncat.vpn.common.log.Log.d("validPeriod==>$validPeriod, nowTime==>$nowTime")
|
||||
Log.d("validPeriod==>$validPeriod, nowTime==>$nowTime")
|
||||
if (validPeriod >= nowTime) {
|
||||
return false
|
||||
}
|
||||
|
|
@ -757,12 +754,12 @@ class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
|
|||
if (clashRunning) {
|
||||
Log.d("clashRunning $clashRunning")
|
||||
} else {
|
||||
startClash()
|
||||
startClash(false)
|
||||
}
|
||||
checkGlo()
|
||||
}?.run {
|
||||
if (isRunning == true && !clashRunning) {
|
||||
startClash()
|
||||
startClash(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -791,10 +788,4 @@ class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
|
|||
baseLoading?.cancel()
|
||||
}
|
||||
}
|
||||
private fun goNewRecharge() {
|
||||
if (activity != null) {
|
||||
val newUiMain = activity as NewMainActivity
|
||||
newUiMain.goBackupRechargeWeb()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -389,18 +389,4 @@ class MainAtyVM : PublicViewMode() {
|
|||
val requestBody: RequestBody = jsonString.toRequestBody("application/json; charset=utf-8".toMediaType())
|
||||
doAsync(HttpReqType.Report){httpApi.getReport(paramsToken,requestBody)}
|
||||
}
|
||||
fun getExpensesRecord(page : NewMainActivity.PageInfo){
|
||||
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 userId = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_USER_ID)!!
|
||||
val params = hashMapOf<String,String>(
|
||||
"phoneNumber" to username,
|
||||
"userId" to userId,
|
||||
"phToken" to phToken,
|
||||
"pageno" to "${page.page}",
|
||||
"pageSize" to "5",
|
||||
)
|
||||
doAsync(HttpReqType.EXPENSES_RECORD){httpApi.phOrderList(params)}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
package com.yingmao.clash.webview
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.CountDownTimer
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import android.webkit.WebChromeClient
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.tencent.mmkv.MMKV
|
||||
import com.yingmao.clash.BuildConfig
|
||||
import com.yingmao.clash.R
|
||||
import com.cncat.vpn.common.log.Log
|
||||
import com.yingmao.clash.base.BaseActivity
|
||||
import com.yingmao.clash.conf.BZYConstants
|
||||
import com.yingmao.clash.listener.AsyncBodyCallback
|
||||
import com.yingmao.clash.util.StatusBarUtils
|
||||
import com.yingmao.clash.vm.LoginAtyVM
|
||||
import com.yingmao.clash.vm.WebViewAtyVM
|
||||
import java.net.URLDecoder
|
||||
import java.net.URLEncoder
|
||||
|
||||
class BZYWebViewKeFu : BaseActivity() {
|
||||
private lateinit var webView: WebView
|
||||
private lateinit var webViewAtyVM: WebViewAtyVM
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.bzy_kefu_webview_layout)
|
||||
|
||||
// requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; //竖屏
|
||||
// StatusBarUtils.with(this).init()
|
||||
webViewAtyVM = ViewModelProvider(this).get(WebViewAtyVM::class.java)
|
||||
observe(this, webViewAtyVM)
|
||||
|
||||
initView()
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
findViewById<View>(R.id.iv_back).setOnClickListener { finish() }
|
||||
webView = findViewById(R.id.webView)
|
||||
setWebView()
|
||||
countDown()
|
||||
}
|
||||
|
||||
private fun countDown() {
|
||||
val timer = object : CountDownTimer(5000, 1000) {
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
Log.d("onFinish")
|
||||
webView.evaluateJavascript("updateStatus()", null)
|
||||
}
|
||||
}
|
||||
timer.start()
|
||||
}
|
||||
|
||||
private fun setWebView() {
|
||||
Log.d("setWebView 1")
|
||||
WebView.setWebContentsDebuggingEnabled(true)
|
||||
Log.d("setWebView 2")
|
||||
val settings = webView.settings
|
||||
settings.javaScriptEnabled = true
|
||||
settings.domStorageEnabled = true
|
||||
settings.allowFileAccess = true
|
||||
Log.d("setWebView 4")
|
||||
webView.webViewClient = object : WebViewClient() {
|
||||
override fun onLoadResource(view: WebView, url: String) {
|
||||
if (url.contains("https://image.crisp.chat/avatar/website") || url.contains("https://client.crisp.chat/static/javascripts/locales")) {
|
||||
webView.evaluateJavascript("updateStatus()", null);
|
||||
}
|
||||
// Log.e("data", "==$url")
|
||||
}
|
||||
}
|
||||
Log.d("setWebView 5")
|
||||
// webView.webChromeClient = object : WebChromeClient() {
|
||||
// override fun onProgressChanged(view: WebView?, newProgress: Int) {
|
||||
//// Log.e("data", "==$newProgress")
|
||||
// }
|
||||
// }
|
||||
|
||||
when {
|
||||
BuildConfig.is_ym -> {
|
||||
ymKefu()
|
||||
}
|
||||
|
||||
BuildConfig.is_tz -> {
|
||||
getTzKefu()
|
||||
}
|
||||
|
||||
BuildConfig.is_yunti -> {
|
||||
getYunTiKefu()
|
||||
}
|
||||
|
||||
else -> {
|
||||
getBzyKefu()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private var kefuHost = ""
|
||||
private fun ymKefu() {
|
||||
val userName = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")
|
||||
var enNmae = URLEncoder.encode(userName, "UTF-8")
|
||||
Log.d("enNmae==>${enNmae}")
|
||||
if (TextUtils.isEmpty(kefuHost)) {
|
||||
var mmkvHost = MMKV.defaultMMKV()
|
||||
.decodeString(BZYConstants.MMKV_KEY_KEFU_HOST, "")
|
||||
// com.cncat.vpn.common.log.Log.d("mmkvHost kf ==>${mmkvHost}")
|
||||
webViewAtyVM.getYmKefuHost(object : AsyncBodyCallback {
|
||||
override suspend fun suc(str: String) {
|
||||
// com.cncat.vpn.common.log.Log.d("str==>${str}")
|
||||
if (str != mmkvHost) {
|
||||
MMKV.defaultMMKV()
|
||||
.encode(BZYConstants.MMKV_KEY_KEFU_HOST, str)
|
||||
}
|
||||
// mmkvHost = str
|
||||
kefuHost = str
|
||||
startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(str + "&app_account=${enNmae}")
|
||||
)
|
||||
)
|
||||
finish()
|
||||
}
|
||||
|
||||
override fun err() {
|
||||
if (!TextUtils.isEmpty(mmkvHost)) {
|
||||
startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(mmkvHost + "&app_account=${enNmae}")
|
||||
)
|
||||
)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
} else {
|
||||
startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(kefuHost + "&app_account=${enNmae}")
|
||||
)
|
||||
)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBzyKefu() {
|
||||
val userName = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")
|
||||
var enNmae = URLEncoder.encode(userName, "UTF-8")
|
||||
Log.d("enNmae==>${enNmae}")
|
||||
if (TextUtils.isEmpty(kefuHost)) {
|
||||
var mmkvHost = MMKV.defaultMMKV()
|
||||
.decodeString(BZYConstants.MMKV_KEY_KEFU_HOST, "")
|
||||
// com.cncat.vpn.common.log.Log.d("mmkvHost kf ==>${mmkvHost}")
|
||||
webViewAtyVM.getBzyKefuHost(object : AsyncBodyCallback {
|
||||
override suspend fun suc(str: String) {
|
||||
// com.cncat.vpn.common.log.Log.d("str==>${str}")
|
||||
if (str != mmkvHost) {
|
||||
MMKV.defaultMMKV()
|
||||
.encode(BZYConstants.MMKV_KEY_KEFU_HOST, str)
|
||||
}
|
||||
// mmkvHost = str
|
||||
kefuHost = str
|
||||
startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(str + "&app_account=${enNmae}")
|
||||
)
|
||||
)
|
||||
finish()
|
||||
}
|
||||
|
||||
override fun err() {
|
||||
if (!TextUtils.isEmpty(mmkvHost)) {
|
||||
startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(mmkvHost + "&app_account=${enNmae}")
|
||||
)
|
||||
)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
} else {
|
||||
startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(kefuHost + "&app_account=${enNmae}")
|
||||
)
|
||||
)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getTzKefu() {
|
||||
val userName = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")
|
||||
var enNmae = URLEncoder.encode(userName, "UTF-8")
|
||||
Log.d("enNmae==>${enNmae}")
|
||||
if (TextUtils.isEmpty(kefuHost)) {
|
||||
var mmkvHost = MMKV.defaultMMKV()
|
||||
.decodeString(BZYConstants.MMKV_KEY_KEFU_HOST, "")
|
||||
// com.cncat.vpn.common.log.Log.d("mmkvHost kf ==>${mmkvHost}")
|
||||
webViewAtyVM.getTzKefuHost(object : AsyncBodyCallback {
|
||||
override suspend fun suc(str: String) {
|
||||
// com.cncat.vpn.common.log.Log.d("str==>${str}")
|
||||
if (str != mmkvHost) {
|
||||
MMKV.defaultMMKV()
|
||||
.encode(BZYConstants.MMKV_KEY_KEFU_HOST, str)
|
||||
}
|
||||
// mmkvHost = str
|
||||
kefuHost = str
|
||||
startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(str + "&app_account=${enNmae}")
|
||||
)
|
||||
)
|
||||
finish()
|
||||
}
|
||||
|
||||
override fun err() {
|
||||
if (!TextUtils.isEmpty(mmkvHost)) {
|
||||
startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(mmkvHost + "&app_account=${enNmae}")
|
||||
)
|
||||
)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
} else {
|
||||
startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(kefuHost + "&app_account=${enNmae}")
|
||||
)
|
||||
)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getYunTiKefu() {
|
||||
val userName = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")
|
||||
var enNmae = URLEncoder.encode(userName, "UTF-8")
|
||||
Log.d("enNmae==>${enNmae}")
|
||||
if (TextUtils.isEmpty(kefuHost)) {
|
||||
var mmkvHost = MMKV.defaultMMKV()
|
||||
.decodeString(BZYConstants.MMKV_KEY_KEFU_HOST, "")
|
||||
// com.cncat.vpn.common.log.Log.d("mmkvHost kf ==>${mmkvHost}")
|
||||
webViewAtyVM.getYunTiKefuHost(object : AsyncBodyCallback {
|
||||
override suspend fun suc(str: String) {
|
||||
// com.cncat.vpn.common.log.Log.d("str==>${str}")
|
||||
if (str != mmkvHost) {
|
||||
MMKV.defaultMMKV()
|
||||
.encode(BZYConstants.MMKV_KEY_KEFU_HOST, str)
|
||||
}
|
||||
kefuHost = str
|
||||
startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(str + "&app_account=${enNmae}")
|
||||
)
|
||||
)
|
||||
finish()
|
||||
}
|
||||
|
||||
override fun err() {
|
||||
if (!TextUtils.isEmpty(mmkvHost)) {
|
||||
startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(mmkvHost + "&app_account=${enNmae}")
|
||||
)
|
||||
)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
} else {
|
||||
startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(kefuHost + "&app_account=${enNmae}")
|
||||
)
|
||||
)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
>
|
||||
|
||||
<RelativeLayout
|
||||
android:gravity="center"
|
||||
android:id="@+id/rl_title_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:visibility="gone"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
android:layout_centerVertical="true"
|
||||
android:id="@+id/iv_back"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:src="@drawable/ic_s_back" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_toStartOf="@+id/iv_more"
|
||||
android:layout_toEndOf="@+id/iv_back"
|
||||
android:gravity="center"
|
||||
android:text="@string/expenses_record"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="21sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_more"
|
||||
tools:ignore="ContentDescription"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:src="@drawable/ic_s_back"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_more"
|
||||
tools:ignore="ContentDescription"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="30dp"
|
||||
android:text="线路测试"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/yellow"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:visibility="invisible" />
|
||||
</RelativeLayout>
|
||||
<FrameLayout
|
||||
android:id="@+id/fl_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/rl_title_bar"
|
||||
/>
|
||||
</RelativeLayout>
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/ic_index_bg">
|
||||
<RelativeLayout
|
||||
android:layout_marginTop="20dp"
|
||||
android:id="@+id/rl_title_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp">
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text=""
|
||||
android:textColor="@color/white"
|
||||
android:textSize="21sp"
|
||||
android:textStyle="bold"
|
||||
/>
|
||||
<ImageView
|
||||
android:layout_centerVertical="true"
|
||||
android:id="@+id/iv_back"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:src="@drawable/ic_s_back"
|
||||
android:contentDescription="@string/kefu"
|
||||
/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<WebView
|
||||
android:layout_below="@+id/rl_title_bar"
|
||||
android:id="@+id/webView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/main_bg" />
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
|
|
@ -106,6 +106,8 @@ subprojects {
|
|||
buildConfigField("boolean", "PREMIUM", "Boolean.parseBoolean(\"false\")")
|
||||
buildConfigField("boolean", "is_back_cn", "false")
|
||||
buildConfigField("boolean", "is_ym", "true")
|
||||
buildConfigField("boolean", "is_tz", "false")
|
||||
buildConfigField("boolean", "is_yunti", "false")
|
||||
buildConfigField("String", "applicationId", "\"com.yingmao.clash\"")
|
||||
buildConfigField("String", "service_url", "\"https://api.ymvpnpro.cc:8700\"")
|
||||
buildConfigField("boolean", "is_free", "false")
|
||||
|
|
|
|||
Loading…
Reference in New Issue