fix: per-app proxy - исправлен формат чтения списка приложений из SharedPreferences
- Удалён устаревший формат с Base64 + ObjectInputStream - Теперь используется стандартный getStringSet() для чтения List<String> - Совместимо с Flutter SharedPreferences plugin - Убраны неиспользуемые импорты (Base64, ByteArrayInputStream, ObjectInputStream)
This commit is contained in:
115
android/app/src/main/kotlin/com/umbrix/app/Settings.kt
Normal file
115
android/app/src/main/kotlin/com/umbrix/app/Settings.kt
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
package com.umbrix.app
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.umbrix.app.bg.ProxyService
|
||||||
|
import com.umbrix.app.bg.VPNService
|
||||||
|
import com.umbrix.app.constant.PerAppProxyMode
|
||||||
|
import com.umbrix.app.constant.ServiceMode
|
||||||
|
import com.umbrix.app.constant.SettingsKey
|
||||||
|
import org.json.JSONObject
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
object Settings {
|
||||||
|
|
||||||
|
private val preferences by lazy {
|
||||||
|
val context = Application.application.applicationContext
|
||||||
|
context.getSharedPreferences("FlutterSharedPreferences", Context.MODE_PRIVATE)
|
||||||
|
}
|
||||||
|
|
||||||
|
var perAppProxyMode: String
|
||||||
|
get() = preferences.getString(SettingsKey.PER_APP_PROXY_MODE, PerAppProxyMode.OFF)!!
|
||||||
|
set(value) = preferences.edit().putString(SettingsKey.PER_APP_PROXY_MODE, value).apply()
|
||||||
|
|
||||||
|
val perAppProxyEnabled: Boolean
|
||||||
|
get() = perAppProxyMode != PerAppProxyMode.OFF
|
||||||
|
|
||||||
|
val perAppProxyList: List<String>
|
||||||
|
get() {
|
||||||
|
val key = if (perAppProxyMode == PerAppProxyMode.INCLUDE) {
|
||||||
|
SettingsKey.PER_APP_PROXY_INCLUDE_LIST
|
||||||
|
} else {
|
||||||
|
SettingsKey.PER_APP_PROXY_EXCLUDE_LIST
|
||||||
|
}
|
||||||
|
// Flutter SharedPreferences plugin сохраняет List<String> как StringSet
|
||||||
|
// Читаем напрямую без дополнительной сериализации
|
||||||
|
return preferences.getStringSet(key, emptySet())?.toList() ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
var activeConfigPath: String
|
||||||
|
get() = preferences.getString(SettingsKey.ACTIVE_CONFIG_PATH, "")!!
|
||||||
|
set(value) = preferences.edit().putString(SettingsKey.ACTIVE_CONFIG_PATH, value).apply()
|
||||||
|
|
||||||
|
var activeProfileName: String
|
||||||
|
get() = preferences.getString(SettingsKey.ACTIVE_PROFILE_NAME, "")!!
|
||||||
|
set(value) = preferences.edit().putString(SettingsKey.ACTIVE_PROFILE_NAME, value).apply()
|
||||||
|
|
||||||
|
var serviceMode: String
|
||||||
|
get() = preferences.getString(SettingsKey.SERVICE_MODE, ServiceMode.VPN)!!
|
||||||
|
set(value) = preferences.edit().putString(SettingsKey.SERVICE_MODE, value).apply()
|
||||||
|
|
||||||
|
var configOptions: String
|
||||||
|
get() = preferences.getString(SettingsKey.CONFIG_OPTIONS, "")!!
|
||||||
|
set(value) = preferences.edit().putString(SettingsKey.CONFIG_OPTIONS, value).apply()
|
||||||
|
|
||||||
|
var debugMode: Boolean
|
||||||
|
get() = preferences.getBoolean(SettingsKey.DEBUG_MODE, false)
|
||||||
|
set(value) = preferences.edit().putBoolean(SettingsKey.DEBUG_MODE, value).apply()
|
||||||
|
|
||||||
|
var disableMemoryLimit: Boolean
|
||||||
|
get() = preferences.getBoolean(SettingsKey.DISABLE_MEMORY_LIMIT, false)
|
||||||
|
set(value) =
|
||||||
|
preferences.edit().putBoolean(SettingsKey.DISABLE_MEMORY_LIMIT, value).apply()
|
||||||
|
|
||||||
|
var dynamicNotification: Boolean
|
||||||
|
get() = preferences.getBoolean(SettingsKey.DYNAMIC_NOTIFICATION, true)
|
||||||
|
set(value) =
|
||||||
|
preferences.edit().putBoolean(SettingsKey.DYNAMIC_NOTIFICATION, value).apply()
|
||||||
|
|
||||||
|
var systemProxyEnabled: Boolean
|
||||||
|
get() = preferences.getBoolean(SettingsKey.SYSTEM_PROXY_ENABLED, true)
|
||||||
|
set(value) =
|
||||||
|
preferences.edit().putBoolean(SettingsKey.SYSTEM_PROXY_ENABLED, value).apply()
|
||||||
|
|
||||||
|
var startedByUser: Boolean
|
||||||
|
get() = preferences.getBoolean(SettingsKey.STARTED_BY_USER, false)
|
||||||
|
set(value) = preferences.edit().putBoolean(SettingsKey.STARTED_BY_USER, value).apply()
|
||||||
|
|
||||||
|
fun serviceClass(): Class<*> {
|
||||||
|
return when (serviceMode) {
|
||||||
|
ServiceMode.VPN -> VPNService::class.java
|
||||||
|
else -> ProxyService::class.java
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var currentServiceMode : String? = null
|
||||||
|
|
||||||
|
suspend fun rebuildServiceMode(): Boolean {
|
||||||
|
var newMode = ServiceMode.NORMAL
|
||||||
|
try {
|
||||||
|
if (serviceMode == ServiceMode.VPN) {
|
||||||
|
newMode = ServiceMode.VPN
|
||||||
|
}
|
||||||
|
} catch (_: Exception) {
|
||||||
|
}
|
||||||
|
if (currentServiceMode == newMode) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
currentServiceMode = newMode
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun needVPNService(): Boolean {
|
||||||
|
val filePath = activeConfigPath
|
||||||
|
if (filePath.isBlank()) return false
|
||||||
|
val content = JSONObject(File(filePath).readText())
|
||||||
|
val inbounds = content.getJSONArray("inbounds")
|
||||||
|
for (index in 0 until inbounds.length()) {
|
||||||
|
val inbound = inbounds.getJSONObject(index)
|
||||||
|
if (inbound.getString("type") == "tun") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user