diff --git a/app/src/main/java/com/github/kr328/clash/MainActivity.kt b/app/src/main/java/com/github/kr328/clash/MainActivity.kt
index 10be5b5..d20b401 100644
--- a/app/src/main/java/com/github/kr328/clash/MainActivity.kt
+++ b/app/src/main/java/com/github/kr328/clash/MainActivity.kt
@@ -13,8 +13,8 @@ import com.github.kr328.clash.common.utils.asBytesString
import com.github.kr328.clash.core.model.General
import com.github.kr328.clash.remote.withClash
import com.github.kr328.clash.remote.withProfile
-import com.github.kr328.clash.utils.startClashService
-import com.github.kr328.clash.utils.stopClashService
+import com.github.kr328.clash.service.util.startClashService
+import com.github.kr328.clash.service.util.stopClashService
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.*
diff --git a/app/src/main/java/com/github/kr328/clash/OnBootReceiver.kt b/app/src/main/java/com/github/kr328/clash/OnBootReceiver.kt
deleted file mode 100644
index 9acb55d..0000000
--- a/app/src/main/java/com/github/kr328/clash/OnBootReceiver.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.github.kr328.clash
-
-import android.content.BroadcastReceiver
-import android.content.Context
-import android.content.Intent
-import com.github.kr328.clash.service.Constants
-import com.github.kr328.clash.utils.startClashService
-
-class OnBootReceiver : BroadcastReceiver() {
- override fun onReceive(context: Context?, intent: Intent?) {
- if (intent?.action != Intent.ACTION_BOOT_COMPLETED || context == null)
- return
-
- if (context.cacheDir.resolve(Constants.CLASH_SERVICE_RUNNING_FILE).exists())
- context.startClashService()
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/github/kr328/clash/ProfilesActivity.kt b/app/src/main/java/com/github/kr328/clash/ProfilesActivity.kt
index 25f7d5e..d803cb6 100644
--- a/app/src/main/java/com/github/kr328/clash/ProfilesActivity.kt
+++ b/app/src/main/java/com/github/kr328/clash/ProfilesActivity.kt
@@ -76,6 +76,8 @@ class ProfilesActivity : BaseActivity(), ProfileAdapter.Callback, ProfilesMenu.C
commitAsync(id)
else
ProfileProvider.releaseTemp(self, id)
+
+ Unit
}
}
diff --git a/app/src/main/java/com/github/kr328/clash/TileService.kt b/app/src/main/java/com/github/kr328/clash/TileService.kt
index a94103e..4ee79e8 100644
--- a/app/src/main/java/com/github/kr328/clash/TileService.kt
+++ b/app/src/main/java/com/github/kr328/clash/TileService.kt
@@ -10,8 +10,8 @@ import android.service.quicksettings.TileService
import com.github.kr328.clash.common.Permissions
import com.github.kr328.clash.common.ids.Intents
import com.github.kr328.clash.remote.RemoteUtils
-import com.github.kr328.clash.utils.startClashService
-import com.github.kr328.clash.utils.stopClashService
+import com.github.kr328.clash.service.util.startClashService
+import com.github.kr328.clash.service.util.stopClashService
class TileService : TileService() {
private var currentProfile = ""
diff --git a/app/src/main/java/com/github/kr328/clash/preference/UiSettings.kt b/app/src/main/java/com/github/kr328/clash/preference/UiSettings.kt
index a7053d0..ac6980e 100644
--- a/app/src/main/java/com/github/kr328/clash/preference/UiSettings.kt
+++ b/app/src/main/java/com/github/kr328/clash/preference/UiSettings.kt
@@ -16,7 +16,6 @@ class UiSettings(context: Context) :
const val DARK_MODE_DARK = "dark"
const val DARK_MODE_LIGHT = "light"
- val ENABLE_VPN = BooleanEntry("enable_vpn", true)
val PROXY_GROUP_SORT = StringEntry("proxy_group_sort", PROXY_SORT_DEFAULT)
val PROXY_PROXY_SORT = StringEntry("proxy_proxy_sort", PROXY_SORT_DEFAULT)
val PROXY_LAST_SELECT_GROUP = StringEntry("proxy_last_select_group", "")
diff --git a/app/src/main/java/com/github/kr328/clash/settings/BehaviorFragment.kt b/app/src/main/java/com/github/kr328/clash/settings/BehaviorFragment.kt
index 47df815..5bba98e 100644
--- a/app/src/main/java/com/github/kr328/clash/settings/BehaviorFragment.kt
+++ b/app/src/main/java/com/github/kr328/clash/settings/BehaviorFragment.kt
@@ -2,10 +2,10 @@ package com.github.kr328.clash.settings
import android.content.pm.PackageManager
import android.os.Bundle
-import com.github.kr328.clash.OnBootReceiver
import com.github.kr328.clash.R
import com.github.kr328.clash.common.util.componentName
import com.github.kr328.clash.remote.Broadcasts
+import com.github.kr328.clash.service.RestartReceiver
import com.github.kr328.clash.service.settings.ServiceSettings
class BehaviorFragment : BaseSettingFragment() {
@@ -40,7 +40,7 @@ class BehaviorFragment : BaseSettingFragment() {
PackageManager.COMPONENT_ENABLED_STATE_DISABLED
requireActivity().packageManager.setComponentEnabledSetting(
- OnBootReceiver::class.componentName,
+ RestartReceiver::class.componentName,
status,
PackageManager.DONT_KILL_APP
)
@@ -48,7 +48,7 @@ class BehaviorFragment : BaseSettingFragment() {
override fun get(): Any? {
val status = requireActivity().packageManager
- .getComponentEnabledSetting(OnBootReceiver::class.componentName)
+ .getComponentEnabledSetting(RestartReceiver::class.componentName)
return status == PackageManager.COMPONENT_ENABLED_STATE_ENABLED
}
diff --git a/app/src/main/java/com/github/kr328/clash/settings/NetworkFragment.kt b/app/src/main/java/com/github/kr328/clash/settings/NetworkFragment.kt
index 97114ab..49ef77b 100644
--- a/app/src/main/java/com/github/kr328/clash/settings/NetworkFragment.kt
+++ b/app/src/main/java/com/github/kr328/clash/settings/NetworkFragment.kt
@@ -32,7 +32,7 @@ class NetworkFragment : BaseSettingFragment() {
override fun onCreateDataStore(): SettingsDataStore {
return SettingsDataStore().apply {
- on(KEY_ENABLE_VPN_SERVICE, UiSettings.ENABLE_VPN.asSource(ui))
+ on(KEY_ENABLE_VPN_SERVICE, ServiceSettings.ENABLE_VPN.asSource(service))
on(BYPASS_PRIVATE_NETWORK, ServiceSettings.BYPASS_PRIVATE_NETWORK.asSource(service))
on(KEY_DNS_HIJACKING, ServiceSettings.DNS_HIJACKING.asSource(service))
on(KEY_DNS_OVERRIDE, ServiceSettings.OVERRIDE_DNS.asSource(service))
diff --git a/app/src/main/java/com/github/kr328/clash/utils/ServiceUtils.kt b/app/src/main/java/com/github/kr328/clash/utils/ServiceUtils.kt
index 53c3022..d71e8b2 100644
--- a/app/src/main/java/com/github/kr328/clash/utils/ServiceUtils.kt
+++ b/app/src/main/java/com/github/kr328/clash/utils/ServiceUtils.kt
@@ -11,22 +11,3 @@ import com.github.kr328.clash.service.ClashService
import com.github.kr328.clash.service.TunService
import com.github.kr328.clash.service.util.sendBroadcastSelf
-fun Context.startClashService(): Intent? {
- val startTun = UiSettings(this).get(UiSettings.ENABLE_VPN)
-
- if (startTun) {
- val vpnRequest = VpnService.prepare(this)
- if (vpnRequest != null)
- return vpnRequest
-
- startForegroundServiceCompat(TunService::class.intent)
- } else {
- startForegroundServiceCompat(ClashService::class.intent)
- }
-
- return null
-}
-
-fun Context.stopClashService() {
- sendBroadcastSelf(Intent(Intents.INTENT_ACTION_REQUEST_STOP))
-}
\ No newline at end of file
diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml
index d79765a..57f1e42 100644
--- a/app/src/main/res/values-zh/strings.xml
+++ b/app/src/main/res/values-zh/strings.xml
@@ -10,7 +10,7 @@
Clash for Android
自动更新 (分钟)
行为
- 启动
+ 重启
绕过私有网络
绕过私有网络地址
取消
@@ -94,8 +94,8 @@
在通知中自动刷新流量
代理组排序
代理排序
- 在系统启动时启动 Clash
- 开机时启动
+ 允许 Clash 自动重启
+ 自动重启
打开 URL 提供程序失败
已停止
支持
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 269b90a..00698cb 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -106,9 +106,9 @@
Network
Interface
- Boot
- Start on Boot
- Start Clash on system boot
+ Restart
+ Auto Restart
+ Allow clash auto restart
Notification
Show Traffic
diff --git a/app/src/main/res/xml/settings_behavior.xml b/app/src/main/res/xml/settings_behavior.xml
index 2eba88d..599fb87 100644
--- a/app/src/main/res/xml/settings_behavior.xml
+++ b/app/src/main/res/xml/settings_behavior.xml
@@ -1,11 +1,11 @@
-
+
+ android:title="@string/auto_restart"
+ android:summary="@string/allow_clash_auto_restart" />
+ android:permission="${applicationId}.permission.RECEIVE_BROADCASTS" />
+
diff --git a/service/src/main/java/com/github/kr328/clash/service/BaseService.kt b/service/src/main/java/com/github/kr328/clash/service/BaseService.kt
index 88876b3..f2b53ab 100644
--- a/service/src/main/java/com/github/kr328/clash/service/BaseService.kt
+++ b/service/src/main/java/com/github/kr328/clash/service/BaseService.kt
@@ -3,7 +3,6 @@ package com.github.kr328.clash.service
import android.app.Service
import android.content.Context
import com.github.kr328.clash.common.util.createLanguageConfigurationContext
-import com.github.kr328.clash.core.Clash
import com.github.kr328.clash.service.settings.ServiceSettings
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
diff --git a/service/src/main/java/com/github/kr328/clash/service/Constants.kt b/service/src/main/java/com/github/kr328/clash/service/Constants.kt
index 6c8b144..c99d94b 100644
--- a/service/src/main/java/com/github/kr328/clash/service/Constants.kt
+++ b/service/src/main/java/com/github/kr328/clash/service/Constants.kt
@@ -8,6 +8,4 @@ object Constants {
const val PROFILE_PROVIDER_SUFFIX = ".profiles"
const val STATUS_PROVIDER_SUFFIX = ".status"
const val SETTING_PROVIDER_SUFFIX = ".settings"
-
- const val CLASH_SERVICE_RUNNING_FILE = "clash_running"
}
\ No newline at end of file
diff --git a/service/src/main/java/com/github/kr328/clash/service/ProfileService.kt b/service/src/main/java/com/github/kr328/clash/service/ProfileService.kt
index 76121c0..303be6d 100644
--- a/service/src/main/java/com/github/kr328/clash/service/ProfileService.kt
+++ b/service/src/main/java/com/github/kr328/clash/service/ProfileService.kt
@@ -4,7 +4,6 @@ import android.content.Intent
import android.net.Uri
import android.os.IBinder
import android.os.RemoteException
-import com.github.kr328.clash.common.utils.Log
import com.github.kr328.clash.service.data.ProfileDao
import com.github.kr328.clash.service.ipc.IStreamCallback
import com.github.kr328.clash.service.model.ProfileMetadata
diff --git a/service/src/main/java/com/github/kr328/clash/service/RestartReceiver.kt b/service/src/main/java/com/github/kr328/clash/service/RestartReceiver.kt
new file mode 100644
index 0000000..b1244ef
--- /dev/null
+++ b/service/src/main/java/com/github/kr328/clash/service/RestartReceiver.kt
@@ -0,0 +1,24 @@
+package com.github.kr328.clash.service
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import com.github.kr328.clash.service.util.startClashService
+
+class RestartReceiver : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent?) {
+ if (context == null)
+ return
+
+ when (intent?.action) {
+ Intent.ACTION_BOOT_COMPLETED, Intent.ACTION_MY_PACKAGE_REPLACED -> {
+ }
+ else -> return
+ }
+
+ ProfileReceiver.tryInitialize(context)
+
+ if (ServiceStatusProvider.shouldStartClashOnBoot)
+ context.startClashService()
+ }
+}
\ No newline at end of file
diff --git a/service/src/main/java/com/github/kr328/clash/service/ServiceStatusProvider.kt b/service/src/main/java/com/github/kr328/clash/service/ServiceStatusProvider.kt
index 8f02479..978d6eb 100644
--- a/service/src/main/java/com/github/kr328/clash/service/ServiceStatusProvider.kt
+++ b/service/src/main/java/com/github/kr328/clash/service/ServiceStatusProvider.kt
@@ -10,12 +10,17 @@ import com.github.kr328.clash.common.Global
class ServiceStatusProvider : ContentProvider() {
companion object {
const val METHOD_PING_CLASH_SERVICE = "pingClashService"
+ private const val CLASH_SERVICE_RUNNING_FILE = "service_running"
var serviceRunning: Boolean = false
set(value) {
field = value
-
- Global.application.cacheDir.resolve(Constants.CLASH_SERVICE_RUNNING_FILE).apply {
+ shouldStartClashOnBoot = value
+ }
+ var shouldStartClashOnBoot: Boolean
+ get() = Global.application.cacheDir.resolve(CLASH_SERVICE_RUNNING_FILE).exists()
+ set(value) {
+ Global.application.cacheDir.resolve(CLASH_SERVICE_RUNNING_FILE).apply {
if (value)
createNewFile()
else
diff --git a/service/src/main/java/com/github/kr328/clash/service/data/DatabaseMigrations.kt b/service/src/main/java/com/github/kr328/clash/service/data/DatabaseMigrations.kt
index 9bcaaf7..2308bc8 100644
--- a/service/src/main/java/com/github/kr328/clash/service/data/DatabaseMigrations.kt
+++ b/service/src/main/java/com/github/kr328/clash/service/data/DatabaseMigrations.kt
@@ -189,6 +189,15 @@ object DatabaseMigrations {
}
database.execSQL("DROP TABLE _profiles")
+
+ val uiSp = Global.application
+ .getSharedPreferences("ui", Context.MODE_PRIVATE)
+ val srvSp = Global.application
+ .getSharedPreferences("service", Context.MODE_PRIVATE)
+
+ srvSp.edit {
+ putBoolean("enable_vpn", uiSp.getBoolean("enable_vpn", true))
+ }
} catch (e: Exception) {
Log.e("Migration failure", e)
}
diff --git a/service/src/main/java/com/github/kr328/clash/service/files/ProfilesResolver.kt b/service/src/main/java/com/github/kr328/clash/service/files/ProfilesResolver.kt
index b71cb45..9fb06f2 100644
--- a/service/src/main/java/com/github/kr328/clash/service/files/ProfilesResolver.kt
+++ b/service/src/main/java/com/github/kr328/clash/service/files/ProfilesResolver.kt
@@ -3,7 +3,6 @@ package com.github.kr328.clash.service.files
import android.content.Context
import android.os.ParcelFileDescriptor
import android.provider.DocumentsContract
-import com.github.kr328.clash.common.utils.Log
import com.github.kr328.clash.service.R
import com.github.kr328.clash.service.data.ProfileDao
import com.github.kr328.clash.service.util.resolveProfileFile
diff --git a/service/src/main/java/com/github/kr328/clash/service/model/Converters.kt b/service/src/main/java/com/github/kr328/clash/service/model/Converters.kt
index d27cf71..d9f6290 100644
--- a/service/src/main/java/com/github/kr328/clash/service/model/Converters.kt
+++ b/service/src/main/java/com/github/kr328/clash/service/model/Converters.kt
@@ -19,7 +19,7 @@ fun ProfileEntity.toProfileMetadata(context: Context): ProfileMetadata {
name = name,
type = type,
uri = Uri.parse(uri),
- source = source?.let { Uri.parse(it)},
+ source = source?.let { Uri.parse(it) },
active = active,
interval = interval,
lastModified = lastModified
diff --git a/service/src/main/java/com/github/kr328/clash/service/model/ProfileMetadata.kt b/service/src/main/java/com/github/kr328/clash/service/model/ProfileMetadata.kt
index 08b07f7..a34cbbc 100644
--- a/service/src/main/java/com/github/kr328/clash/service/model/ProfileMetadata.kt
+++ b/service/src/main/java/com/github/kr328/clash/service/model/ProfileMetadata.kt
@@ -19,7 +19,7 @@ data class ProfileMetadata(
val active: Boolean,
val interval: Long,
val lastModified: Long
-): Parcelable {
+) : Parcelable {
enum class Type {
FILE, URL, EXTERNAL, UNKNOWN
}
diff --git a/service/src/main/java/com/github/kr328/clash/service/settings/ServiceSettings.kt b/service/src/main/java/com/github/kr328/clash/service/settings/ServiceSettings.kt
index b1c6a1c..b194879 100644
--- a/service/src/main/java/com/github/kr328/clash/service/settings/ServiceSettings.kt
+++ b/service/src/main/java/com/github/kr328/clash/service/settings/ServiceSettings.kt
@@ -16,6 +16,8 @@ class ServiceSettings(preference: SharedPreferences) :
const val ACCESS_CONTROL_MODE_BLACKLIST = "access_control_mode_blacklist"
const val ACCESS_CONTROL_MODE_WHITELIST = "access_control_mode_whitelist"
+ val ENABLE_VPN =
+ BooleanEntry("enable_vpn", true)
val LANGUAGE =
StringEntry("language", "")
val BYPASS_PRIVATE_NETWORK =
diff --git a/service/src/main/java/com/github/kr328/clash/service/util/BroadcastUtils.kt b/service/src/main/java/com/github/kr328/clash/service/util/BroadcastUtils.kt
index d278b6c..34e000f 100644
--- a/service/src/main/java/com/github/kr328/clash/service/util/BroadcastUtils.kt
+++ b/service/src/main/java/com/github/kr328/clash/service/util/BroadcastUtils.kt
@@ -4,12 +4,12 @@ import android.content.Context
import android.content.Intent
import com.github.kr328.clash.common.Permissions
import com.github.kr328.clash.common.ids.Intents
-import com.github.kr328.clash.common.utils.Log
-import java.lang.Exception
fun Context.sendBroadcastSelf(intent: Intent) {
- this.sendBroadcast(intent.setPackage(this.packageName),
- Permissions.PERMISSION_RECEIVE_BROADCASTS)
+ this.sendBroadcast(
+ intent.setPackage(this.packageName),
+ Permissions.PERMISSION_RECEIVE_BROADCASTS
+ )
}
fun Context.broadcastProfileChanged() {
diff --git a/service/src/main/java/com/github/kr328/clash/service/util/ServiceUtils.kt b/service/src/main/java/com/github/kr328/clash/service/util/ServiceUtils.kt
new file mode 100644
index 0000000..efdc510
--- /dev/null
+++ b/service/src/main/java/com/github/kr328/clash/service/util/ServiceUtils.kt
@@ -0,0 +1,31 @@
+package com.github.kr328.clash.service.util
+
+import android.content.Context
+import android.content.Intent
+import android.net.VpnService
+import com.github.kr328.clash.common.ids.Intents
+import com.github.kr328.clash.common.util.intent
+import com.github.kr328.clash.common.util.startForegroundServiceCompat
+import com.github.kr328.clash.service.ClashService
+import com.github.kr328.clash.service.TunService
+import com.github.kr328.clash.service.settings.ServiceSettings
+
+fun Context.startClashService(): Intent? {
+ val startTun = ServiceSettings(this).get(ServiceSettings.ENABLE_VPN)
+
+ if (startTun) {
+ val vpnRequest = VpnService.prepare(this)
+ if (vpnRequest != null)
+ return vpnRequest
+
+ startForegroundServiceCompat(TunService::class.intent)
+ } else {
+ startForegroundServiceCompat(ClashService::class.intent)
+ }
+
+ return null
+}
+
+fun Context.stopClashService() {
+ sendBroadcastSelf(Intent(Intents.INTENT_ACTION_REQUEST_STOP))
+}
\ No newline at end of file