From a45aa489e8b671944f0dcb9bfa87e24cd4f61cd9 Mon Sep 17 00:00:00 2001
From: Tamim Hossain <132823494+CodeWithTamim@users.noreply.github.com>
Date: Sat, 28 Sep 2024 13:25:47 +0600
Subject: [PATCH] Feature/add auto start (#3609)
* Update Kotlin Version In Readme.md
Update Kotlin Version In Readme.md
* Size check replaced with 'isNotEmpty()
* Fixed size check issue
* Add auto-start VPN feature
* Update SettingsActivity.kt
---------
Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
---
V2rayNG/app/src/main/AndroidManifest.xml | 90 ++++++++++---------
.../main/kotlin/com/v2ray/ang/AppConfig.kt | 7 +-
.../com/v2ray/ang/receiver/BootReceiver.kt | 18 ++++
.../v2ray/ang/service/V2RayServiceManager.kt | 3 +-
.../kotlin/com/v2ray/ang/ui/MainActivity.kt | 3 +-
.../com/v2ray/ang/ui/SettingsActivity.kt | 8 +-
.../kotlin/com/v2ray/ang/util/MmkvManager.kt | 10 +++
V2rayNG/app/src/main/res/values/strings.xml | 3 +
.../app/src/main/res/xml/pref_settings.xml | 4 +
9 files changed, 98 insertions(+), 48 deletions(-)
create mode 100644 V2rayNG/app/src/main/kotlin/com/v2ray/ang/receiver/BootReceiver.kt
diff --git a/V2rayNG/app/src/main/AndroidManifest.xml b/V2rayNG/app/src/main/AndroidManifest.xml
index bae5335a..2a5159e5 100644
--- a/V2rayNG/app/src/main/AndroidManifest.xml
+++ b/V2rayNG/app/src/main/AndroidManifest.xml
@@ -5,9 +5,9 @@
-->
-
+
+ android:name=".ui.SettingsActivity"
+ android:exported="false" />
+ android:name=".ui.PerAppProxyActivity"
+ android:exported="false" />
+ android:name=".ui.ScannerActivity"
+ android:exported="false" />
+ android:name=".ui.LogcatActivity"
+ android:exported="false" />
+ android:name=".ui.RoutingSettingActivity"
+ android:exported="false" />
+ android:name=".ui.RoutingEditActivity"
+ android:exported="false" />
+ android:name=".ui.SubSettingActivity"
+ android:exported="false" />
+ android:name=".ui.UserAssetActivity"
+ android:exported="false" />
+ android:name=".ui.UserAssetUrlActivity"
+ android:exported="false" />
+ android:name=".ui.SubEditActivity"
+ android:exported="false" />
+ android:name=".ui.ScScannerActivity"
+ android:exported="false" />
+ android:name=".ui.UrlSchemeActivity"
+ android:exported="true">
@@ -145,16 +145,16 @@
+ android:name=".ui.AboutActivity"
+ android:exported="false" />
@@ -170,8 +170,8 @@
+ android:process=":RunSoLibV2RayDaemon" />
+
+
+
+
+
@@ -215,8 +221,8 @@
@@ -225,8 +231,8 @@
diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AppConfig.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AppConfig.kt
index f17c93f5..cdcb5909 100644
--- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AppConfig.kt
+++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AppConfig.kt
@@ -48,12 +48,12 @@ object AppConfig {
const val PREF_ALLOW_INSECURE = "pref_allow_insecure"
const val PREF_SOCKS_PORT = "pref_socks_port"
const val PREF_HTTP_PORT = "pref_http_port"
-
const val PREF_REMOTE_DNS = "pref_remote_dns"
const val PREF_DOMESTIC_DNS = "pref_domestic_dns"
const val PREF_DELAY_TEST_URL = "pref_delay_test_url"
const val PREF_LOGLEVEL = "pref_core_loglevel"
const val PREF_MODE = "pref_mode"
+ const val PREF_IS_BOOTED = "pref_is_booted"
/** Cache keys. */
const val CACHE_SUBSCRIPTION_ID = "cache_subscription_id"
@@ -106,6 +106,7 @@ object AppConfig {
const val DNS_DIRECT = "223.5.5.5"
const val DNS_VPN = "1.1.1.1"
+
/** Ports and addresses for various services. */
const val PORT_LOCAL_DNS = "10853"
const val PORT_SOCKS = "10808"
@@ -149,4 +150,8 @@ object AppConfig {
const val WIREGUARD = "wireguard://"
const val TUIC = "tuic://"
const val HYSTERIA2 = "hysteria2://"
+
+ /** Give a good name to this, IDK*/
+ const val VPN = "VPN"
+
}
diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/receiver/BootReceiver.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/receiver/BootReceiver.kt
new file mode 100644
index 00000000..6d92d2f0
--- /dev/null
+++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/receiver/BootReceiver.kt
@@ -0,0 +1,18 @@
+package com.v2ray.ang.receiver
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import com.v2ray.ang.service.V2RayServiceManager
+import com.v2ray.ang.util.MmkvManager
+
+class BootReceiver : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent?) {
+ if (Intent.ACTION_BOOT_COMPLETED == intent?.action && MmkvManager.decodeStartOnBoot()) {
+ if (MmkvManager.getSelectServer().isNullOrEmpty()) {
+ return
+ }
+ V2RayServiceManager.startV2Ray(context!!)
+ }
+ }
+}
\ No newline at end of file
diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/V2RayServiceManager.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/V2RayServiceManager.kt
index 97819a40..fea3dd49 100644
--- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/V2RayServiceManager.kt
+++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/V2RayServiceManager.kt
@@ -16,6 +16,7 @@ import androidx.core.app.NotificationCompat
import com.v2ray.ang.AppConfig
import com.v2ray.ang.AppConfig.ANG_PACKAGE
import com.v2ray.ang.AppConfig.TAG_DIRECT
+import com.v2ray.ang.AppConfig.VPN
import com.v2ray.ang.R
import com.v2ray.ang.dto.ServerConfig
import com.v2ray.ang.extension.toSpeedString
@@ -72,7 +73,7 @@ object V2RayServiceManager {
} else {
context.toast(R.string.toast_services_start)
}
- val intent = if ((settingsStorage?.decodeString(AppConfig.PREF_MODE) ?: "VPN") == "VPN") {
+ val intent = if ((settingsStorage?.decodeString(AppConfig.PREF_MODE) ?: VPN) == VPN) {
Intent(context.applicationContext, V2RayVpnService::class.java)
} else {
Intent(context.applicationContext, V2RayProxyOnlyService::class.java)
diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainActivity.kt
index ab31d8f0..d3c49190 100644
--- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainActivity.kt
+++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainActivity.kt
@@ -29,6 +29,7 @@ import com.google.android.material.navigation.NavigationView
import com.google.android.material.tabs.TabLayout
import com.tbruyelle.rxpermissions3.RxPermissions
import com.v2ray.ang.AppConfig
+import com.v2ray.ang.AppConfig.VPN
import com.v2ray.ang.R
import com.v2ray.ang.databinding.ActivityMainBinding
import com.v2ray.ang.dto.EConfigType
@@ -88,7 +89,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
binding.fab.setOnClickListener {
if (mainViewModel.isRunning.value == true) {
Utils.stopVService(this)
- } else if ((settingsStorage?.decodeString(AppConfig.PREF_MODE) ?: "VPN") == "VPN") {
+ } else if ((settingsStorage?.decodeString(AppConfig.PREF_MODE) ?: VPN) == VPN) {
val intent = VpnService.prepare(this)
if (intent == null) {
startV2Ray()
diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SettingsActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SettingsActivity.kt
index 818c211c..86247836 100644
--- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SettingsActivity.kt
+++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SettingsActivity.kt
@@ -15,6 +15,7 @@ import androidx.work.PeriodicWorkRequest
import androidx.work.multiprocess.RemoteWorkManager
import com.v2ray.ang.AngApplication
import com.v2ray.ang.AppConfig
+import com.v2ray.ang.AppConfig.VPN
import com.v2ray.ang.R
import com.v2ray.ang.extension.toLongEx
import com.v2ray.ang.service.SubscriptionUpdater
@@ -172,7 +173,7 @@ class SettingsActivity : BaseActivity() {
override fun onStart() {
super.onStart()
- updateMode(settingsStorage.decodeString(AppConfig.PREF_MODE, "VPN"))
+ updateMode(settingsStorage.decodeString(AppConfig.PREF_MODE, VPN))
localDns?.isChecked = settingsStorage.getBoolean(AppConfig.PREF_LOCAL_DNS_ENABLED, false)
fakeDns?.isChecked = settingsStorage.getBoolean(AppConfig.PREF_FAKE_DNS_ENABLED, false)
localDnsPort?.summary = settingsStorage.decodeString(AppConfig.PREF_LOCAL_DNS_PORT, AppConfig.PORT_LOCAL_DNS)
@@ -220,7 +221,7 @@ class SettingsActivity : BaseActivity() {
).forEach { key ->
key?.text = key?.summary.toString()
}
-
+
listOf(
AppConfig.PREF_SNIFFING_ENABLED,
).forEach { key ->
@@ -230,6 +231,7 @@ class SettingsActivity : BaseActivity() {
listOf(
AppConfig.PREF_ROUTE_ONLY_ENABLED,
+ AppConfig.PREF_IS_BOOTED,
AppConfig.PREF_BYPASS_APPS,
AppConfig.PREF_SPEED_ENABLED,
AppConfig.PREF_CONFIRM_REMOVE,
@@ -258,7 +260,7 @@ class SettingsActivity : BaseActivity() {
}
private fun updateMode(mode: String?) {
- val vpn = mode == "VPN"
+ val vpn = mode == VPN
perAppProxy?.isEnabled = vpn
perAppProxy?.isChecked = settingsStorage.getBoolean(AppConfig.PREF_PER_APP_PROXY, false)
localDns?.isEnabled = vpn
diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/MmkvManager.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/MmkvManager.kt
index 1eae4ebf..ea1a8441 100644
--- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/MmkvManager.kt
+++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/MmkvManager.kt
@@ -2,6 +2,7 @@ package com.v2ray.ang.util
import com.google.gson.Gson
import com.tencent.mmkv.MMKV
+import com.v2ray.ang.AppConfig.PREF_IS_BOOTED
import com.v2ray.ang.AppConfig.PREF_ROUTING_RULESET
import com.v2ray.ang.dto.AssetUrlItem
import com.v2ray.ang.dto.ProfileItem
@@ -28,6 +29,7 @@ object MmkvManager {
private val mainStorage by lazy { MMKV.mmkvWithID(ID_MAIN, MMKV.MULTI_PROCESS_MODE) }
val settingsStorage by lazy { MMKV.mmkvWithID(ID_SETTING, MMKV.MULTI_PROCESS_MODE) }
+ val serverStorage by lazy { MMKV.mmkvWithID(ID_SERVER_CONFIG, MMKV.MULTI_PROCESS_MODE) }
private val serverStorage by lazy { MMKV.mmkvWithID(ID_SERVER_CONFIG, MMKV.MULTI_PROCESS_MODE) }
private val profileStorage by lazy { MMKV.mmkvWithID(ID_PROFILE_CONFIG, MMKV.MULTI_PROCESS_MODE) }
private val serverAffStorage by lazy { MMKV.mmkvWithID(ID_SERVER_AFF, MMKV.MULTI_PROCESS_MODE) }
@@ -51,6 +53,14 @@ object MmkvManager {
mainStorage.encode(KEY_ANG_CONFIGS, Gson().toJson(serverList))
}
+ fun encodeStartOnBoot(startOnBoot: Boolean) {
+ settingsStorage.encode(PREF_IS_BOOTED, startOnBoot)
+ }
+
+ fun decodeStartOnBoot(): Boolean {
+ return settingsStorage.decodeBool(PREF_IS_BOOTED, false)
+ }
+
fun decodeServerList(): MutableList {
val json = mainStorage.decodeString(KEY_ANG_CONFIGS)
return if (json.isNullOrBlank()) {
diff --git a/V2rayNG/app/src/main/res/values/strings.xml b/V2rayNG/app/src/main/res/values/strings.xml
index 7f7b09a6..19939084 100644
--- a/V2rayNG/app/src/main/res/values/strings.xml
+++ b/V2rayNG/app/src/main/res/values/strings.xml
@@ -130,6 +130,9 @@
Advanced Settings
VPN Settings
Per-app proxy
+ Auto start
+ Automatically start VPN if a server has already been selected
+
General: Checked App is proxy, unchecked direct connection; \nbypass mode: checked app directly connected, unchecked proxy. \nThe option to automatically select the proxy application in the menu
Mux Settings
diff --git a/V2rayNG/app/src/main/res/xml/pref_settings.xml b/V2rayNG/app/src/main/res/xml/pref_settings.xml
index ca13d534..0649030f 100644
--- a/V2rayNG/app/src/main/res/xml/pref_settings.xml
+++ b/V2rayNG/app/src/main/res/xml/pref_settings.xml
@@ -13,6 +13,10 @@
android:key="pref_route_only_enabled"
android:summary="@string/summary_pref_route_only_enabled"
android:title="@string/title_pref_route_only_enabled" />
+