Merge branch 'yijianlian_NewUI' into yijianlian_NewUI_tobase

# Conflicts:
#	app/src/main/java/com/yingmao/clash/act/SplashActivity.kt
#	build.gradle.kts
This commit is contained in:
11111 2026-01-05 12:17:40 +08:00
commit 539354e273
10 changed files with 121 additions and 179 deletions

View File

@ -17,7 +17,6 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.* import android.widget.*
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@ -51,6 +50,7 @@ import java.io.File
import androidx.core.graphics.toColorInt import androidx.core.graphics.toColorInt
import androidx.core.net.toUri import androidx.core.net.toUri
import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.yingmao.clash.levellog.AppLog
class LoginActivity : BaseActivity(), View.OnClickListener { class LoginActivity : BaseActivity(), View.OnClickListener {
private lateinit var loginViewMode: LoginAtyVM private lateinit var loginViewMode: LoginAtyVM
@ -114,7 +114,7 @@ class LoginActivity : BaseActivity(), View.OnClickListener {
super.httpSuccess(httpStatus) super.httpSuccess(httpStatus)
if (httpStatus.reqType == HttpReqType.LOGIN) { if (httpStatus.reqType == HttpReqType.LOGIN) {
val rsp = httpStatus.rsp val rsp = httpStatus.rsp
com.cncat.vpn.common.log.Log.d("HttpReqType.LOGIN rsp==>${rsp}") AppLog.i("SplashActivity", "httpSuccess HttpReqType.LOGIN ${rsp}")
if (rsp is LoginRsp) { if (rsp is LoginRsp) {
if (rsp.code == "1000") { if (rsp.code == "1000") {
val mmkv = MMKV.defaultMMKV() val mmkv = MMKV.defaultMMKV()
@ -135,6 +135,7 @@ class LoginActivity : BaseActivity(), View.OnClickListener {
} else if (httpStatus.reqType == HttpReqType.CHECK_LOGIN) { } else if (httpStatus.reqType == HttpReqType.CHECK_LOGIN) {
hideLoadingDialog() hideLoadingDialog()
val rsp = httpStatus.rsp val rsp = httpStatus.rsp
AppLog.i("SplashActivity", "httpSuccess HttpReqType.CHECK_LOGIN ${rsp}")
if (rsp is CheckLoginRsp) { if (rsp is CheckLoginRsp) {
if (rsp.code == 0) { if (rsp.code == 0) {
rsp.data?.let { MainApplication.setUserInfo(it) } rsp.data?.let { MainApplication.setUserInfo(it) }
@ -161,6 +162,7 @@ class LoginActivity : BaseActivity(), View.OnClickListener {
} else if (httpStatus.reqType == HttpReqType.GETAPPVERION) { } else if (httpStatus.reqType == HttpReqType.GETAPPVERION) {
(httpStatus.rsp as AppVersionCheckRsp).let { aver -> (httpStatus.rsp as AppVersionCheckRsp).let { aver ->
com.cncat.vpn.common.log.Log.i("appVersionCheck ==>$aver") com.cncat.vpn.common.log.Log.i("appVersionCheck ==>$aver")
AppLog.i("SplashActivity", "httpSuccess HttpReqType.GETAPPVERION ${aver}")
if (aver.code == 200) { if (aver.code == 200) {
aver.data?.let { md -> aver.data?.let { md ->
if (md.isForce) { //强制更新 if (md.isForce) { //强制更新
@ -182,6 +184,7 @@ class LoginActivity : BaseActivity(), View.OnClickListener {
override fun httpFailure(httpStatus: HttpStatus.Failure) { override fun httpFailure(httpStatus: HttpStatus.Failure) {
super.httpFailure(httpStatus) super.httpFailure(httpStatus)
if (httpStatus.reqType == HttpReqType.LOGIN) { if (httpStatus.reqType == HttpReqType.LOGIN) {
AppLog.i("SplashActivity", "httpFailure HttpReqType.LOGIN ${httpStatus.msg}")
SplashHelper(splashAtyVM).getHostWithFallback { success -> SplashHelper(splashAtyVM).getHostWithFallback { success ->
MainScope().launch { MainScope().launch {
if (success) { if (success) {
@ -229,6 +232,7 @@ class LoginActivity : BaseActivity(), View.OnClickListener {
} }
} }
} else if (httpStatus.reqType == HttpReqType.CHECK_LOGIN) { } else if (httpStatus.reqType == HttpReqType.CHECK_LOGIN) {
AppLog.i("SplashActivity", "httpFailure HttpReqType.CHECK_LOGIN ${httpStatus.msg}")
if (::rxDialogShapeLoading.isInitialized && rxDialogShapeLoading.isShowing) { if (::rxDialogShapeLoading.isInitialized && rxDialogShapeLoading.isShowing) {
rxDialogShapeLoading.cancel() rxDialogShapeLoading.cancel()
} }

View File

@ -46,8 +46,8 @@ import com.yingmao.clash.base.BaseActivity
import com.yingmao.clash.conf.BZYConstants import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.conf.Conf import com.yingmao.clash.conf.Conf
import com.yingmao.clash.entity.CheckLoginRsp import com.yingmao.clash.entity.CheckLoginRsp
import com.yingmao.clash.entity.NodeGroupItem
import com.yingmao.clash.fragment.home.HomeFragment import com.yingmao.clash.fragment.home.HomeFragment
import com.yingmao.clash.fragment.home.HomeFragment.Companion.clashRunning
import com.yingmao.clash.fragment.setting.SettingFragment import com.yingmao.clash.fragment.setting.SettingFragment
import com.yingmao.clash.fragment.vip.vipFragment import com.yingmao.clash.fragment.vip.vipFragment
import com.yingmao.clash.levellog.AppLog import com.yingmao.clash.levellog.AppLog
@ -90,9 +90,6 @@ import java.util.UUID
class MainActivity : BaseActivity() { class MainActivity : BaseActivity() {
private lateinit var mainAtyVM: MainAtyVM private lateinit var mainAtyVM: MainAtyVM
private var payResultLoading: RxDialogShapeLoading? = null private var payResultLoading: RxDialogShapeLoading? = null
private val clashRunning: Boolean
get() = Remote.broadcasts.clashRunning
private var timer: Timer? = null private var timer: Timer? = null
private var uTimerTask: TimerTask? = null private var uTimerTask: TimerTask? = null
private var newMainActGlo: Boolean = false private var newMainActGlo: Boolean = false
@ -130,6 +127,7 @@ class MainActivity : BaseActivity() {
private var mainBroadcastReceiver: BroadcastReceiver? = null private var mainBroadcastReceiver: BroadcastReceiver? = null
val trafficStatisticsData = MutableLiveData<String>() val trafficStatisticsData = MutableLiveData<String>()
suspend fun setSub2(url: String) { suspend fun setSub2(url: String) {
try {
profileBinder?.let { pm -> profileBinder?.let { pm ->
pm.queryAll().forEach { itemPro -> pm.queryAll().forEach { itemPro ->
if (itemPro.name != Conf.getClashConfName(MainApplication.getApp()?.applicationContext)) { if (itemPro.name != Conf.getClashConfName(MainApplication.getApp()?.applicationContext)) {
@ -186,6 +184,9 @@ class MainActivity : BaseActivity() {
} }
} }
} }
}catch (e: Exception){
AppLog.e("HomeFragment", "setSub2() Error===>",e)
}
} }
} }
@ -233,8 +234,6 @@ class MainActivity : BaseActivity() {
requestPermissionLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS) requestPermissionLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS)
} }
} }
//初始进入 将日志采集开关变为不开启
MMKV.defaultMMKV().encode(BZYConstants.BehaviorLogSwitch, false)
} }
inner class NodeListBR : BroadcastReceiver() { inner class NodeListBR : BroadcastReceiver() {
@ -285,7 +284,10 @@ class MainActivity : BaseActivity() {
aivHome.setImageResource(R.drawable.yjl_home_page_choose) aivHome.setImageResource(R.drawable.yjl_home_page_choose)
aivCenter.setImageResource(R.drawable.yjl_user_page) aivCenter.setImageResource(R.drawable.yjl_user_page)
aivVip.setImageResource(R.drawable.yjl_vip_page) aivVip.setImageResource(R.drawable.yjl_vip_page)
checkVPN() if(clashRunning){
checkVPN()
}
} }
aivCenter.setOnClickListener { aivCenter.setOnClickListener {
@ -294,7 +296,10 @@ class MainActivity : BaseActivity() {
aivHome.setImageResource(R.drawable.yjl_home_page) aivHome.setImageResource(R.drawable.yjl_home_page)
aivCenter.setImageResource(R.drawable.yjl_user_page_choose) aivCenter.setImageResource(R.drawable.yjl_user_page_choose)
aivVip.setImageResource(R.drawable.yjl_vip_page) aivVip.setImageResource(R.drawable.yjl_vip_page)
checkVPN() Log.i("AAAAAAAAAAAAAAAAAAA clashRunning${clashRunning}")
if(clashRunning){
checkVPN()
}
} }
aivVip.setOnClickListener { aivVip.setOnClickListener {
@ -336,8 +341,10 @@ class MainActivity : BaseActivity() {
when (httpStatus.reqType) { when (httpStatus.reqType) {
HttpReqType.GET_AIRNODES -> { HttpReqType.GET_AIRNODES -> {
val data = httpStatus.rsp as SubscriptionRsp val data = httpStatus.rsp as SubscriptionRsp
AppLog.i("SplashActivity", "httpSuccess HttpReqType.GET_AIRNODES ${data}")
if (data.code != "1000") { if (data.code != "1000") {
RxToast.error(resources.getString(R.string.NodeAcquisitionFailed) + "${data.msg}") RxToast.error(resources.getString(R.string.NodeAcquisitionFailed) + "${data.msg}")
AppLog.i("MainActivity", "httpSuccess GET_AIRNODES===>${data.msg}")
} }
data.data.let { netSubUrl -> data.data.let { netSubUrl ->
if (netSubUrl.isNotEmpty()) { if (netSubUrl.isNotEmpty()) {
@ -366,6 +373,7 @@ class MainActivity : BaseActivity() {
HttpReqType.GetActivity -> { HttpReqType.GetActivity -> {
val data = httpStatus.rsp as GetActivityRsp val data = httpStatus.rsp as GetActivityRsp
AppLog.i("SplashActivity", "httpSuccess HttpReqType.GetActivity ${data}")
if (data.code == 200) { if (data.code == 200) {
if (data.data.data.list.isNotEmpty()) { if (data.data.data.list.isNotEmpty()) {
data.data.data.list[0].redirectLink.let { data.data.data.list[0].redirectLink.let {
@ -393,6 +401,7 @@ class MainActivity : BaseActivity() {
HttpReqType.CHECK_LOGIN -> { HttpReqType.CHECK_LOGIN -> {
(httpStatus.rsp as CheckLoginRsp).let { checkLoginRsp -> (httpStatus.rsp as CheckLoginRsp).let { checkLoginRsp ->
AppLog.i("SplashActivity", "httpSuccess HttpReqType.CHECK_LOGIN ${checkLoginRsp}")
if (checkLoginRsp.code == 0) { if (checkLoginRsp.code == 0) {
val mmkv = MMKV.defaultMMKV() val mmkv = MMKV.defaultMMKV()
val oldExpireTime = val oldExpireTime =
@ -426,6 +435,7 @@ class MainActivity : BaseActivity() {
HttpReqType.PHDOWNLOADURL -> { HttpReqType.PHDOWNLOADURL -> {
(httpStatus.rsp as PhDownloadUrlRsp).let { (httpStatus.rsp as PhDownloadUrlRsp).let {
AppLog.i("SplashActivity", "httpSuccess HttpReqType.PHDOWNLOADURL ${it}")
if (it.code == 1000) { if (it.code == 1000) {
val lastNotice = val lastNotice =
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_NOTICE_READ, "") MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_NOTICE_READ, "")
@ -460,6 +470,7 @@ class MainActivity : BaseActivity() {
HttpReqType.EXPENSES_RECORD ->{ HttpReqType.EXPENSES_RECORD ->{
if(httpStatus.rsp is ExpensesRecordRsp){ if(httpStatus.rsp is ExpensesRecordRsp){
httpStatus.rsp.let { expensesRecordRsp -> httpStatus.rsp.let { expensesRecordRsp ->
AppLog.i("SplashActivity", "httpSuccess HttpReqType.EXPENSES_RECORD ${expensesRecordRsp}")
if(expensesRecordRsp.code == "1000"){ if(expensesRecordRsp.code == "1000"){
if(expensesRecordRsp.data != null) { if(expensesRecordRsp.data != null) {
val expensesRecordList = expensesRecordRsp.data.expensesRecords val expensesRecordList = expensesRecordRsp.data.expensesRecords
@ -497,6 +508,7 @@ class MainActivity : BaseActivity() {
} }
HttpReqType.Report->{ HttpReqType.Report->{
(httpStatus.rsp as AppVersionCheckRsp).let { (httpStatus.rsp as AppVersionCheckRsp).let {
AppLog.i("SplashActivity", "httpSuccess HttpReqType.Report ${it}")
android.util.Log.i("reqType:","data:::"+it.code) android.util.Log.i("reqType:","data:::"+it.code)
if(it.code==200){ if(it.code==200){
//上报百度支付功能 //上报百度支付功能
@ -515,6 +527,7 @@ class MainActivity : BaseActivity() {
when (httpStatus.reqType) { when (httpStatus.reqType) {
HttpReqType.HEARTBEAT -> { HttpReqType.HEARTBEAT -> {
Logger.d("心跳失败") Logger.d("心跳失败")
AppLog.i("HomeFragment", " httpFailure HEARTBEAT===>${httpStatus.msg}")
if (5 <= HEART_BEAT_FAILURE_FREQUENCY) { if (5 <= HEART_BEAT_FAILURE_FREQUENCY) {
HEART_BEAT_FAILURE_FREQUENCY = 0 HEART_BEAT_FAILURE_FREQUENCY = 0
Logger.d("心跳失败次数超过10次退出登录") Logger.d("心跳失败次数超过10次退出登录")
@ -524,15 +537,18 @@ class MainActivity : BaseActivity() {
} }
HttpReqType.CHECK_LOGIN -> { HttpReqType.CHECK_LOGIN -> {
AppLog.i("HomeFragment", " httpFailure CHECK_LOGIN===>${httpStatus.msg}")
payResultLoading?.dismiss() payResultLoading?.dismiss()
RxToast.error(resources.getString(R.string.QueryFailed)+ httpStatus.msg) RxToast.error(resources.getString(R.string.QueryFailed)+ httpStatus.msg)
} }
HttpReqType.GET_AIRNODES -> { HttpReqType.GET_AIRNODES -> {
AppLog.i("HomeFragment", " httpFailure GET_AIRNODES===>${httpStatus.msg}")
Logger.e("获取节点异常:${httpStatus.msg}") Logger.e("获取节点异常:${httpStatus.msg}")
} }
HttpReqType.VIPSIGN -> { HttpReqType.VIPSIGN -> {
AppLog.i("HomeFragment", " httpFailure VIPSIGN===>${httpStatus.msg}")
RxToast.error(resources.getString(R.string.CheckFailed) + httpStatus.msg) RxToast.error(resources.getString(R.string.CheckFailed) + httpStatus.msg)
} }
@ -805,19 +821,14 @@ class MainActivity : BaseActivity() {
aivVip.setImageResource(R.drawable.yjl_vip_page_choose) aivVip.setImageResource(R.drawable.yjl_vip_page_choose)
} }
fun checkVPN(){ fun checkVPN(){
val behaviorLogSwitch = launch(Dispatchers.IO) {
MMKV.defaultMMKV().decodeBool(BZYConstants.BehaviorLogSwitch, false) val isVPN =Utils.isVpnActive(this@MainActivity)
if(behaviorLogSwitch){ AppLog.i("NewMainActivity", "VPN是否打开::::${isVPN}")
launch(Dispatchers.IO) { val vpnCheChek =Utils.checkHttpOk("https://www.youtube.com")
val isVPN =Utils.isVpnActive(this@MainActivity) AppLog.i("NewMainActivity", "校验访问https://www.youtube.com::${vpnCheChek}")
AppLog.i("NewMainActivity", "VPN是否打开::::${isVPN}")
val vpnCheChek =Utils.checkHttpOk("https://www.youtube.com")
AppLog.i("NewMainActivity", "校验访问https://www.youtube.com::${vpnCheChek}")
val vpnCheChekGoogle =Utils.checkHttpOk("https://www.google.com") val vpnCheChekGoogle =Utils.checkHttpOk("https://www.google.com")
AppLog.i("NewMainActivity", "校验访问https://www.google.com::${vpnCheChekGoogle}") AppLog.i("NewMainActivity", "校验访问https://www.google.com::${vpnCheChekGoogle}")
}
} }
} }
} }

View File

@ -44,6 +44,7 @@ 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_PASSWORD
import com.yingmao.clash.conf.BZYConstants.Companion.MMKV_KEY_REMEMBER_USERNAME import com.yingmao.clash.conf.BZYConstants.Companion.MMKV_KEY_REMEMBER_USERNAME
import com.yingmao.clash.entity.CheckLoginRsp import com.yingmao.clash.entity.CheckLoginRsp
import com.yingmao.clash.levellog.AppLog
import com.yingmao.clash.listener.DownLoadListener import com.yingmao.clash.listener.DownLoadListener
import com.yingmao.clash.net.http.HttpReqType import com.yingmao.clash.net.http.HttpReqType
import com.yingmao.clash.net.http.HttpStatus import com.yingmao.clash.net.http.HttpStatus

View File

@ -70,6 +70,5 @@ class BZYConstants {
const val applicationMode = "ApplicationMode" const val applicationMode = "ApplicationMode"
const val is_splash_first = "is_splash_first" const val is_splash_first = "is_splash_first"
const val ScreenFlag="screenshotFlag" const val ScreenFlag="screenshotFlag"
const val BehaviorLogSwitch = "BehaviorLogSwitch"
} }
} }

View File

@ -12,7 +12,6 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.text.TextUtils import android.text.TextUtils
import android.view.View import android.view.View
import android.view.WindowManager
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.ImageView import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
@ -30,8 +29,10 @@ import androidx.lifecycle.lifecycleScope
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.customview.customView import com.afollestad.materialdialogs.customview.customView
import com.afollestad.materialdialogs.customview.getCustomView import com.afollestad.materialdialogs.customview.getCustomView
import com.cncat.vpn.common.compat.startForegroundServiceCompat
import com.cncat.vpn.common.constants.Intents import com.cncat.vpn.common.constants.Intents
import com.cncat.vpn.common.log.Log import com.cncat.vpn.common.log.Log
import com.cncat.vpn.common.util.intent
import com.cncat.vpn.core.Clash import com.cncat.vpn.core.Clash
import com.cncat.vpn.core.model.TunnelState import com.cncat.vpn.core.model.TunnelState
import com.cncat.vpn.service.model.Profile import com.cncat.vpn.service.model.Profile
@ -40,6 +41,7 @@ import com.google.gson.Gson
import com.google.gson.JsonParser import com.google.gson.JsonParser
import com.orhanobut.logger.Logger import com.orhanobut.logger.Logger
import com.tencent.mmkv.MMKV import com.tencent.mmkv.MMKV
import com.yingmao.clash.BuildConfig
import com.yingmao.clash.R import com.yingmao.clash.R
import com.yingmao.clash.act.ChangeNodeActivity.ProxyMode import com.yingmao.clash.act.ChangeNodeActivity.ProxyMode
import com.yingmao.clash.act.MainActivity import com.yingmao.clash.act.MainActivity
@ -50,12 +52,15 @@ import com.yingmao.clash.act.MainActivity.Companion.newUuid
import com.yingmao.clash.act.MainActivity.Companion.profileBinder import com.yingmao.clash.act.MainActivity.Companion.profileBinder
import com.yingmao.clash.act.MainActivity.Companion.subUrl import com.yingmao.clash.act.MainActivity.Companion.subUrl
import com.yingmao.clash.act.NodeGroupActivity import com.yingmao.clash.act.NodeGroupActivity
import com.yingmao.clash.app.MainApplication
import com.yingmao.clash.conf.BZYConstants import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.conf.BZYConstants.Companion.MMKV_KEY_REMEMBER_USERNAME
import com.yingmao.clash.conf.Conf import com.yingmao.clash.conf.Conf
import com.yingmao.clash.entity.NodeGroupItem import com.yingmao.clash.entity.NodeGroupItem
import com.yingmao.clash.fragment.AccelerateViewModel import com.yingmao.clash.fragment.AccelerateViewModel
import com.yingmao.clash.fragment.BaseFragment import com.yingmao.clash.fragment.BaseFragment
import com.yingmao.clash.levellog.AppLog import com.yingmao.clash.levellog.AppLog
import com.yingmao.clash.levellog.LogcatService
import com.yingmao.clash.net.http.HttpReqType import com.yingmao.clash.net.http.HttpReqType
import com.yingmao.clash.net.http.HttpStatus import com.yingmao.clash.net.http.HttpStatus
import com.yingmao.clash.net.http.entity.AppStartupStatus import com.yingmao.clash.net.http.entity.AppStartupStatus
@ -77,6 +82,7 @@ import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.net.URL
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
@ -182,6 +188,17 @@ open class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispa
observe(this, accelerateViewModel) observe(this, accelerateViewModel)
initSS() initSS()
accelerateViewModel.getSelectNodeInfo() accelerateViewModel.getSelectNodeInfo()
val selectedName =
MMKV.defaultMMKV().decodeString(MMKV_KEY_REMEMBER_USERNAME, "")
val equipmentModel = Utils.getEquipmentModel()
val validPeriod = MMKV.defaultMMKV().decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD)
AppLog.i("HomeFragment", "用户账号===>${selectedName}")
AppLog.i("HomeFragment", "版本号===>${requireActivity().resources.getString(R.string.currentVersionNumber) + "${BuildConfig.VERSION_NAME}." + BuildConfig.productId}")
AppLog.i("HomeFragment", "用户有效时长===>${validPeriod}")
AppLog.i("HomeFragment", "用户是否过期===>${checkExpire()}")
AppLog.i("HomeFragment", "机型数据===>${equipmentModel}")
AppLog.i("HomeFragment", "订阅连接地址===>${subUrl}")
AppLog.i("HomeFragment", "OAID===>${MainApplication.Companion.OAID}")
} }
@ -298,7 +315,8 @@ open class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispa
if (connectId != -1) { if (connectId != -1) {
accelerateViewModel.appStopStatus(connectId) accelerateViewModel.appStopStatus(connectId)
} }
//关闭内核日志采集Service
requireActivity().stopService(LogcatService::class.intent)
} }
rxDialogSureCancel.show() rxDialogSureCancel.show()
@ -333,7 +351,8 @@ open class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispa
if(networkAvailable){ if(networkAvailable){
showLoading(resources.getString(R.string.Starting), requireContext()) showLoading(resources.getString(R.string.Starting), requireContext())
startClash(true) startClash(true)
//开启完毕之后开启定时器, //开启完成之后开始采集日志
behaviorLog()
}else{ }else{
RxToast.error("网络不可用,请打开网络!") RxToast.error("网络不可用,请打开网络!")
AppLog.i("NewAccFragment", "networkAvailable ${networkAvailable}") AppLog.i("NewAccFragment", "networkAvailable ${networkAvailable}")
@ -446,23 +465,23 @@ open class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispa
withContext(Dispatchers.Main){ withContext(Dispatchers.Main){
hideLoading() hideLoading()
stateChanged(CLASH_STOP, false) stateChanged(CLASH_STOP, false)
ivAccelerate.setImageResource(R.mipmap.yjl_home_clink_bg)
RxToast.info(resources.getString(R.string.vpnStartingError)) RxToast.info(resources.getString(R.string.vpnStartingError))
AppLog.i("NewAccFragment", "vpnRequest::VPN权限点击取消") AppLog.i("NewAccFragment", "vpnRequest::VPN权限点击取消")
} }
} }
} else { } else {
withContext(Dispatchers.Main) {
tvClick.text=resources.getString(R.string.Accelerating)
ivAccelerate.setImageResource(R.mipmap.yjl_home_clink_select_bg)
hideLoading()
}
accelerateViewModel.appStartupStatus() accelerateViewModel.appStartupStatus()
} }
} catch (e: Exception) { } catch (e: Exception) {
stopUTimer() stopUTimer()
e.printStackTrace() e.printStackTrace()
} }
withContext(Dispatchers.Main) {
tvClick.text=resources.getString(R.string.Accelerating)
ivAccelerate.setImageResource(R.mipmap.yjl_home_clink_select_bg)
hideLoading()
// checkGlo()
}
} }
} }
@ -913,10 +932,12 @@ open class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispa
when (httpStatus.reqType) { when (httpStatus.reqType) {
HttpReqType.AppStartupStatus -> { HttpReqType.AppStartupStatus -> {
Log.d("AppStartupStatus is Failure ${httpStatus.msg}") Log.d("AppStartupStatus is Failure ${httpStatus.msg}")
AppLog.i("HomeFragment", " httpFailure AppStartupStatus===>${httpStatus.msg}")
} }
HttpReqType.AppStopStatus -> { HttpReqType.AppStopStatus -> {
Log.d("AppStopStatus is Failure ${httpStatus.msg}") Log.d("AppStopStatus is Failure ${httpStatus.msg}")
AppLog.i("HomeFragment", " httpFailure AppStopStatus===>${httpStatus.msg}")
} }
else -> { else -> {
@ -1107,4 +1128,8 @@ open class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispa
} }
return mList return mList
} }
fun behaviorLog(){
AppLog.i("HomeFragment", "加速开启前 订阅连接地址 behaviorLog===>${subUrl}")
requireContext().startService(LogcatService::class.intent)
}
} }

View File

@ -8,8 +8,6 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.text.TextUtils import android.text.TextUtils
import android.view.View import android.view.View
import android.widget.FrameLayout import android.widget.FrameLayout
@ -22,8 +20,6 @@ import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.customview.customView
import com.alibaba.sdk.android.oss.ClientException import com.alibaba.sdk.android.oss.ClientException
import com.alibaba.sdk.android.oss.OSSClient import com.alibaba.sdk.android.oss.OSSClient
import com.alibaba.sdk.android.oss.ServiceException import com.alibaba.sdk.android.oss.ServiceException
@ -33,7 +29,6 @@ import com.alibaba.sdk.android.oss.common.auth.OSSStsTokenCredentialProvider
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask import com.alibaba.sdk.android.oss.internal.OSSAsyncTask
import com.alibaba.sdk.android.oss.model.PutObjectRequest import com.alibaba.sdk.android.oss.model.PutObjectRequest
import com.alibaba.sdk.android.oss.model.PutObjectResult import com.alibaba.sdk.android.oss.model.PutObjectResult
import com.cncat.vpn.common.compat.startForegroundServiceCompat
import com.cncat.vpn.common.log.Log import com.cncat.vpn.common.log.Log
import com.cncat.vpn.common.util.intent import com.cncat.vpn.common.util.intent
import com.hjq.permissions.OnPermissionCallback import com.hjq.permissions.OnPermissionCallback
@ -47,21 +42,19 @@ import com.yingmao.clash.act.ActivityActivity
import com.yingmao.clash.act.AgreementAndPrivacyActivity import com.yingmao.clash.act.AgreementAndPrivacyActivity
import com.yingmao.clash.act.BandPhoneActivity import com.yingmao.clash.act.BandPhoneActivity
import com.yingmao.clash.act.MainActivity import com.yingmao.clash.act.MainActivity
import com.yingmao.clash.act.MainActivity.Companion.newUuid
import com.yingmao.clash.act.MainActivity.Companion.profileBinder import com.yingmao.clash.act.MainActivity.Companion.profileBinder
import com.yingmao.clash.act.MainActivity.Companion.setSub2 import com.yingmao.clash.act.MainActivity.Companion.setSub2
import com.yingmao.clash.act.MainActivity.Companion.subUrl import com.yingmao.clash.act.MainActivity.Companion.subUrl
import com.yingmao.clash.act.MainActivity.Companion.trafficStatisticsData
import com.yingmao.clash.act.SettingActivity import com.yingmao.clash.act.SettingActivity
import com.yingmao.clash.act.ShareActivity import com.yingmao.clash.act.ShareActivity
import com.yingmao.clash.act.SplashHelper import com.yingmao.clash.act.SplashHelper
import com.yingmao.clash.app.MainApplication import com.yingmao.clash.app.MainApplication
import com.yingmao.clash.levellog.LogcatService
import com.yingmao.clash.conf.BZYConstants import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.entity.SettingPageBean import com.yingmao.clash.entity.SettingPageBean
import com.yingmao.clash.fragment.BaseFragment import com.yingmao.clash.fragment.BaseFragment
import com.yingmao.clash.fragment.home.HomeFragment.Companion.clashRunning import com.yingmao.clash.fragment.home.HomeFragment.Companion.clashRunning
import com.yingmao.clash.levellog.AppLog import com.yingmao.clash.levellog.AppLog
import com.yingmao.clash.levellog.LogcatService
import com.yingmao.clash.net.http.HttpReqType import com.yingmao.clash.net.http.HttpReqType
import com.yingmao.clash.net.http.HttpStatus import com.yingmao.clash.net.http.HttpStatus
import com.yingmao.clash.net.http.entity.ParamData import com.yingmao.clash.net.http.entity.ParamData
@ -72,6 +65,7 @@ import com.yingmao.clash.util.CommonUtils
import com.yingmao.clash.util.DataUtils import com.yingmao.clash.util.DataUtils
import com.yingmao.clash.util.DataUtils.getAllFilePath import com.yingmao.clash.util.DataUtils.getAllFilePath
import com.yingmao.clash.util.PayUtils import com.yingmao.clash.util.PayUtils
import com.yingmao.clash.util.Utils
import com.yingmao.clash.view.RxToast import com.yingmao.clash.view.RxToast
import com.yingmao.clash.view.dialog.DialogBandChoose import com.yingmao.clash.view.dialog.DialogBandChoose
import com.yingmao.clash.view.dialog.DialogDoMainChoose import com.yingmao.clash.view.dialog.DialogDoMainChoose
@ -184,24 +178,11 @@ class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatc
R.drawable.switching_item_tag, R.drawable.switching_item_tag,
) )
val logDirParent = "applogs" val upLoadData =SettingPageBean(
val logDir = File(requireActivity().filesDir, logDirParent) 7,
val processName =getProcessName() "上传日志",
val logFile = File(logDir, "$processName.log") R.drawable.user_uplog_icon,
val upLoadData = if(logFile.exists()){ )
SettingPageBean(
7,
"上传日志",
R.drawable.user_uplog_icon,
)
}else{
SettingPageBean(
7,
"采集日志",
R.drawable.user_uplog_icon,
)
}
val privacyPolicyItem= SettingPageBean( val privacyPolicyItem= SettingPageBean(
8, 8,
resources.getString(R.string.PrivacyPolicy), resources.getString(R.string.PrivacyPolicy),
@ -294,30 +275,23 @@ class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatc
} }
7->{ 7->{
if(itemData.name=="上传日志"){ val getIsGlo= MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_GLOBAL_MODEL, false)
showLoading(resources.getString(R.string.UploadingInProgress), requireActivity()) if(clashRunning&&getIsGlo){
mainAtyVM.getUploadParameters() RxToast.info("全局模式暂不支持上传日志,请切换到智能模式或关闭加速!")
settingPageList[itemData.type-1].name="采集日志"
settingAdapter.notifyItemChanged(itemData.type-1)
MMKV.defaultMMKV().encode(BZYConstants.BehaviorLogSwitch, false)
requireActivity().stopService(LogcatService::class.intent)
}else{ }else{
MaterialDialog(requireActivity()).show { if(clashRunning){
this.cancelable(true) checkVPN()
cornerRadius(res = R.dimen.dp_15) }
customView( val logDirParent = "applogs"
R.layout.logsings_dialog_layout, val logDir = File(requireActivity().filesDir, logDirParent)
scrollable = false, val processName =getProcessName()
noVerticalPadding = true, val logFile = File(logDir, "$processName.log")
horizontalPadding = false if(logFile.exists()){
) showLoading(resources.getString(R.string.UploadingInProgress), requireActivity())
val tvSure = findViewById<TextView>(R.id.tvSure) mainAtyVM.getUploadParameters()
tvSure.setOnClickListener { requireActivity().stopService(LogcatService::class.intent)
settingPageList[itemData.type-1].name="上传日志" }else{
settingAdapter.notifyItemChanged(itemData.type-1) RxToast.info("暂时未采集到相关日志数据")
requireActivity().startForegroundServiceCompat(LogcatService::class.intent)
dismiss()
}
} }
} }
} }
@ -873,8 +847,6 @@ class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatc
hideLoading() hideLoading()
val deleteFile = DataUtils.deleteFile(filePath) val deleteFile = DataUtils.deleteFile(filePath)
Log.i("PutObjectRequest deleteFile ${deleteFile}") Log.i("PutObjectRequest deleteFile ${deleteFile}")
AppLog.i("LogcatService", "删除删除成功deleteFile::${deleteFile}")
MMKV.defaultMMKV().encode(BZYConstants.BehaviorLogSwitch, false)
RxToast.info(resources.getString(R.string.BehaviorLogSuccessfully)) RxToast.info(resources.getString(R.string.BehaviorLogSuccessfully))
} }
}else{ }else{
@ -908,4 +880,15 @@ class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatc
} }
fun checkVPN(){
launch(Dispatchers.IO) {
val isVPN =Utils.isVpnActive(requireActivity())
AppLog.i("NewMainActivity", "VPN是否打开::::${isVPN}")
val vpnCheChek =Utils.checkHttpOk("https://www.youtube.com")
AppLog.i("NewMainActivity", "校验访问https://www.youtube.com::${vpnCheChek}")
val vpnCheChekGoogle =Utils.checkHttpOk("https://www.google.com")
AppLog.i("NewMainActivity", "校验访问https://www.google.com::${vpnCheChekGoogle}")
}
}
} }

View File

@ -27,19 +27,14 @@ object AppLog {
msg: String, msg: String,
tr: Throwable? tr: Throwable?
) { ) {
val behaviorLogSwitch = LogDispatcher.enqueue(
MMKV.defaultMMKV().decodeBool(BZYConstants.BehaviorLogSwitch, false) LogEvent(
if(behaviorLogSwitch){ time = System.currentTimeMillis(),
LogDispatcher.enqueue( level = level,
LogEvent( tag = tag,
time = System.currentTimeMillis(), message = msg,
level = level, throwable = tr
tag = tag,
message = msg,
throwable = tr
)
) )
} )
} }
} }

View File

@ -1,6 +1,5 @@
package com.yingmao.clash.levellog package com.yingmao.clash.levellog
import android.app.PendingIntent
import android.app.Service import android.app.Service
import android.content.ComponentName import android.content.ComponentName
import android.content.Intent import android.content.Intent
@ -11,25 +10,12 @@ import android.os.IBinder
import android.os.IInterface import android.os.IInterface
import android.util.Log import android.util.Log
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.core.app.NotificationChannelCompat
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.cncat.vpn.common.compat.getColorCompat
import com.cncat.vpn.common.compat.pendingIntentFlags
import com.cncat.vpn.common.compat.startForegroundCompat
import com.cncat.vpn.common.util.intent import com.cncat.vpn.common.util.intent
import com.cncat.vpn.core.model.LogMessage import com.cncat.vpn.core.model.LogMessage
import com.cncat.vpn.service.RemoteService import com.cncat.vpn.service.RemoteService
import com.cncat.vpn.service.remote.ILogObserver import com.cncat.vpn.service.remote.ILogObserver
import com.cncat.vpn.service.remote.IRemoteService import com.cncat.vpn.service.remote.IRemoteService
import com.cncat.vpn.service.remote.unwrap import com.cncat.vpn.service.remote.unwrap
import com.tencent.mmkv.MMKV
import com.yingmao.clash.R
import com.yingmao.clash.act.MainActivity
import com.yingmao.clash.act.SettingActivity
import com.yingmao.clash.app.MainApplication
import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.util.Utils
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.NonCancellable
@ -46,7 +32,6 @@ class LogcatService : Service(), CoroutineScope by CoroutineScope(Dispatchers.De
Log.i("LogcatServiceClose","onServiceDisconnected::${name}") Log.i("LogcatServiceClose","onServiceDisconnected::${name}")
stopSelf() stopSelf()
} }
@RequiresApi(Build.VERSION_CODES.KITKAT) @RequiresApi(Build.VERSION_CODES.KITKAT)
override fun onServiceConnected(name: ComponentName?, service: IBinder?) { override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
Log.i("LogcatServiceConnect","onServiceConnected::${name}") Log.i("LogcatServiceConnect","onServiceConnected::${name}")
@ -56,25 +41,13 @@ class LogcatService : Service(), CoroutineScope by CoroutineScope(Dispatchers.De
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
running = true
createNotificationChannel()
showNotification()
bindService(RemoteService::class.intent, connection, BIND_AUTO_CREATE) bindService(RemoteService::class.intent, connection, BIND_AUTO_CREATE)
} }
override fun onDestroy() { override fun onDestroy() {
cancel() cancel()
unbindService(connection) unbindService(connection)
stopSelf()
stopForeground(true)
running = false
super.onDestroy() super.onDestroy()
} }
@ -100,14 +73,6 @@ class LogcatService : Service(), CoroutineScope by CoroutineScope(Dispatchers.De
val channel = Channel<LogMessage>(CACHE_CAPACITY) val channel = Channel<LogMessage>(CACHE_CAPACITY)
try { try {
MMKV.defaultMMKV().encode(BZYConstants.Companion.BehaviorLogSwitch, true)
val selectedName =
MMKV.defaultMMKV().decodeString(BZYConstants.Companion.NODE_SELECTED_NAME_KEY, "")
val equipmentModel = Utils.getEquipmentModel()
AppLog.i("LogcatService", "selectedName===>${selectedName}")
AppLog.i("LogcatService", "用户是否过期===>${checkExpire()}")
AppLog.i("LogcatService", "机型数据===>${equipmentModel}")
AppLog.i("LogcatService", "OAID===>${MainApplication.Companion.OAID}")
val observer = object : ILogObserver { val observer = object : ILogObserver {
override fun newItem(log: LogMessage) { override fun newItem(log: LogMessage) {
channel.trySend(log) channel.trySend(log)
@ -131,52 +96,7 @@ class LogcatService : Service(), CoroutineScope by CoroutineScope(Dispatchers.De
} }
} }
private fun createNotificationChannel() {
NotificationManagerCompat.from(this)
.createNotificationChannel(
NotificationChannelCompat.Builder(
CHANNEL_ID,
NotificationManagerCompat.IMPORTANCE_DEFAULT
).setName(getString(R.string.clash_logcat)).build()
)
}
private fun showNotification() {
val notification = NotificationCompat
.Builder(this, CHANNEL_ID)
.setSmallIcon(R.mipmap.oneclickconnection)
.setColor(getColorCompat(R.color.color_clash))
.setContentTitle(getString(R.string.clash_logcat))
.setContentText("采集中")
.setContentIntent(
PendingIntent.getActivity(
this,
R.id.nf_logcat_status,
MainActivity::class.intent
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP),
pendingIntentFlags(PendingIntent.FLAG_UPDATE_CURRENT)
)
)
.build()
startForegroundCompat(R.id.nf_logcat_status, notification)
}
companion object { companion object {
private const val CHANNEL_ID = "clash_logcat_channel_id"
private const val CACHE_CAPACITY = 129 private const val CACHE_CAPACITY = 129
var running: Boolean = false
}
private fun checkExpire(): Boolean {
val validPeriod = MMKV.defaultMMKV().decodeLong(BZYConstants.Companion.MMKV_KEY_VPN_VALID_PERIOD)
if (validPeriod > 0) {
val nowTime = System.currentTimeMillis();
com.cncat.vpn.common.log.Log.d("validPeriod==>$validPeriod, nowTime==>$nowTime")
if (validPeriod >= nowTime) {
return false
}
}
return true
} }
} }

View File

@ -15,8 +15,12 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import com.yingmao.clash.levellog.AppLog import com.yingmao.clash.levellog.AppLog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import org.json.JSONObject
import java.net.Inet4Address
import java.net.NetworkInterface import java.net.NetworkInterface
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
import java.security.MessageDigest import java.security.MessageDigest

View File

@ -492,8 +492,8 @@
</string> </string>
<string name="modelchanging">模式切换中</string> <string name="modelchanging">模式切换中</string>
<string name="modelchangSuccess">模式切换成功</string> <string name="modelchangSuccess">模式切换成功</string>
<string name="BehaviorLogSuccessfully">行为日志上传成功!</string> <string name="BehaviorLogSuccessfully">日志上传成功!</string>
<string name="BehaviorLogError">行为日志上传失败!</string> <string name="BehaviorLogError">日志上传失败!</string>
<string name="vpnStartingError">VPN权限未允许 请设置允许!</string> <string name="vpnStartingError">VPN权限未允许 请设置允许!</string>
<string name="CloseChooseNode">请关闭加速后在切换节点</string> <string name="CloseChooseNode">请关闭加速后在切换节点</string>
</resources> </resources>