mirror of
https://github.com/openlibrecommunity/olcng.git
synced 2026-07-03 14:05:17 +02:00
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>
This commit is contained in:
@@ -5,9 +5,9 @@
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
android:smallScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:largeScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:smallScreens="true"
|
||||
android:xlargeScreens="true" />
|
||||
|
||||
<uses-sdk
|
||||
@@ -44,13 +44,13 @@
|
||||
<!-- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> -->
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
|
||||
<application
|
||||
android:name=".AngApplication"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:banner="@mipmap/ic_banner"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppThemeDayNight"
|
||||
@@ -77,57 +77,57 @@
|
||||
android:resource="@xml/shortcuts" />
|
||||
</activity>
|
||||
<activity
|
||||
android:exported="false"
|
||||
android:name=".ui.ServerActivity"
|
||||
android:exported="false"
|
||||
android:windowSoftInputMode="stateUnchanged" />
|
||||
<activity
|
||||
android:exported="false"
|
||||
android:name=".ui.ServerCustomConfigActivity"
|
||||
android:exported="false"
|
||||
android:windowSoftInputMode="stateUnchanged" />
|
||||
<activity
|
||||
android:exported="false"
|
||||
android:name=".ui.SettingsActivity" />
|
||||
android:name=".ui.SettingsActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:exported="false"
|
||||
android:name=".ui.PerAppProxyActivity" />
|
||||
android:name=".ui.PerAppProxyActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:exported="false"
|
||||
android:name=".ui.ScannerActivity" />
|
||||
android:name=".ui.ScannerActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:exported="false"
|
||||
android:name=".ui.LogcatActivity" />
|
||||
android:name=".ui.LogcatActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:exported="false"
|
||||
android:name=".ui.RoutingSettingActivity" />
|
||||
android:name=".ui.RoutingSettingActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:exported="false"
|
||||
android:name=".ui.RoutingEditActivity" />
|
||||
android:name=".ui.RoutingEditActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:exported="false"
|
||||
android:name=".ui.SubSettingActivity" />
|
||||
android:name=".ui.SubSettingActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:exported="false"
|
||||
android:name=".ui.UserAssetActivity" />
|
||||
android:name=".ui.UserAssetActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:exported="false"
|
||||
android:name=".ui.UserAssetUrlActivity" />
|
||||
android:name=".ui.UserAssetUrlActivity"
|
||||
android:exported="false" />
|
||||
|
||||
<activity
|
||||
android:exported="false"
|
||||
android:name=".ui.SubEditActivity" />
|
||||
android:name=".ui.SubEditActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:exported="false"
|
||||
android:name=".ui.ScScannerActivity" />
|
||||
android:name=".ui.ScScannerActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:exported="false"
|
||||
android:name=".ui.ScSwitchActivity"
|
||||
android:excludeFromRecents="true"
|
||||
android:exported="false"
|
||||
android:process=":RunSoLibV2RayDaemon"
|
||||
android:theme="@style/AppTheme.NoActionBar.Translucent" />
|
||||
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name=".ui.UrlSchemeActivity">
|
||||
android:name=".ui.UrlSchemeActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
@@ -145,16 +145,16 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:exported="false"
|
||||
android:name=".ui.AboutActivity" />
|
||||
android:name=".ui.AboutActivity"
|
||||
android:exported="false" />
|
||||
|
||||
<service
|
||||
android:name=".service.V2RayVpnService"
|
||||
android:enabled="true"
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="specialUse"
|
||||
android:label="@string/app_name"
|
||||
android:permission="android.permission.BIND_VPN_SERVICE"
|
||||
android:foregroundServiceType="specialUse"
|
||||
android:process=":RunSoLibV2RayDaemon">
|
||||
<intent-filter>
|
||||
<action android:name="android.net.VpnService" />
|
||||
@@ -170,8 +170,8 @@
|
||||
<service
|
||||
android:name=".service.V2RayProxyOnlyService"
|
||||
android:exported="false"
|
||||
android:label="@string/app_name"
|
||||
android:foregroundServiceType="specialUse"
|
||||
android:label="@string/app_name"
|
||||
android:process=":RunSoLibV2RayDaemon">
|
||||
<property
|
||||
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
|
||||
@@ -181,12 +181,11 @@
|
||||
<service
|
||||
android:name=".service.V2RayTestService"
|
||||
android:exported="false"
|
||||
android:process=":RunSoLibV2RayDaemon"
|
||||
/>
|
||||
android:process=":RunSoLibV2RayDaemon" />
|
||||
|
||||
<receiver
|
||||
android:exported="true"
|
||||
android:name=".receiver.WidgetProvider"
|
||||
android:exported="true"
|
||||
android:process=":RunSoLibV2RayDaemon">
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
@@ -197,13 +196,20 @@
|
||||
<action android:name="com.v2ray.ang.action.activity" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver
|
||||
android:name=".receiver.BootReceiver"
|
||||
android:label="BootReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<service
|
||||
android:exported="true"
|
||||
android:name=".service.QSTileService"
|
||||
android:exported="true"
|
||||
android:foregroundServiceType="specialUse"
|
||||
android:icon="@drawable/ic_stat_name"
|
||||
android:label="@string/app_tile_name"
|
||||
android:foregroundServiceType="specialUse"
|
||||
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
|
||||
android:process=":RunSoLibV2RayDaemon">
|
||||
<intent-filter>
|
||||
@@ -215,8 +221,8 @@
|
||||
</service>
|
||||
<!-- =====================Tasker===================== -->
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name=".ui.TaskerActivity"
|
||||
android:exported="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
@@ -225,8 +231,8 @@
|
||||
</activity>
|
||||
|
||||
<receiver
|
||||
android:exported="true"
|
||||
android:name=".receiver.TaskerReceiver"
|
||||
android:exported="true"
|
||||
android:process=":RunSoLibV2RayDaemon">
|
||||
<intent-filter>
|
||||
<action android:name="com.twofortyfouram.locale.intent.action.FIRE_SETTING" />
|
||||
|
||||
@@ -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"
|
||||
|
||||
}
|
||||
|
||||
@@ -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!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<String> {
|
||||
val json = mainStorage.decodeString(KEY_ANG_CONFIGS)
|
||||
return if (json.isNullOrBlank()) {
|
||||
|
||||
@@ -130,6 +130,9 @@
|
||||
<string name="title_advanced">Advanced Settings</string>
|
||||
<string name="title_vpn_settings">VPN Settings</string>
|
||||
<string name="title_pref_per_app_proxy">Per-app proxy</string>
|
||||
<string name="title_pref_is_booted">Auto start</string>
|
||||
<string name="summary_pref_is_booted">Automatically start VPN if a server has already been selected</string>
|
||||
|
||||
<string name="summary_pref_per_app_proxy">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</string>
|
||||
|
||||
<string name="title_mux_settings">Mux Settings</string>
|
||||
|
||||
@@ -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" />
|
||||
<CheckBoxPreference
|
||||
android:key="pref_is_booted"
|
||||
android:summary="@string/summary_pref_is_booted"
|
||||
android:title="@string/title_pref_is_booted" />
|
||||
|
||||
<PreferenceCategory android:title="@string/title_vpn_settings">
|
||||
<CheckBoxPreference
|
||||
|
||||
Reference in New Issue
Block a user