add auto update subscriptions with interval
This commit is contained in:
1 parent
99307ab8f0
commit
062c0d8ddb
10 files changed
+257
-17
No files matched your search
@@ -132,4 +132,9 @@ dependencies {
|
|||||||
implementation 'com.blacksquircle.ui:language-json:2.1.1'
|
implementation 'com.blacksquircle.ui:language-json:2.1.1'
|
||||||
implementation 'io.github.g00fy2.quickie:quickie-bundled:1.6.0'
|
implementation 'io.github.g00fy2.quickie:quickie-bundled:1.6.0'
|
||||||
implementation 'com.google.zxing:core:3.5.1'
|
implementation 'com.google.zxing:core:3.5.1'
|
||||||
|
|
||||||
|
def work_version = "2.8.1"
|
||||||
|
|
||||||
|
implementation "androidx.work:work-runtime-ktx:$work_version"
|
||||||
|
implementation "androidx.work:work-multiprocess:$work_version"
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,20 @@
|
|||||||
package com.v2ray.ang
|
package com.v2ray.ang
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import androidx.multidex.MultiDexApplication
|
import androidx.multidex.MultiDexApplication
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
|
import androidx.work.Configuration
|
||||||
import com.tencent.mmkv.MMKV
|
import com.tencent.mmkv.MMKV
|
||||||
|
|
||||||
class AngApplication : MultiDexApplication() {
|
class AngApplication : MultiDexApplication(), Configuration.Provider {
|
||||||
companion object {
|
companion object {
|
||||||
const val PREF_LAST_VERSION = "pref_last_version"
|
const val PREF_LAST_VERSION = "pref_last_version"
|
||||||
|
lateinit var application: AngApplication
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun attachBaseContext(base: Context?) {
|
||||||
|
super.attachBaseContext(base)
|
||||||
|
application = this
|
||||||
}
|
}
|
||||||
|
|
||||||
var firstRun = false
|
var firstRun = false
|
||||||
@@ -25,4 +33,10 @@ class AngApplication : MultiDexApplication() {
|
|||||||
//Logger.init().logLevel(if (BuildConfig.DEBUG) LogLevel.FULL else LogLevel.NONE)
|
//Logger.init().logLevel(if (BuildConfig.DEBUG) LogLevel.FULL else LogLevel.NONE)
|
||||||
MMKV.initialize(this)
|
MMKV.initialize(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getWorkManagerConfiguration(): Configuration {
|
||||||
|
return Configuration.Builder()
|
||||||
|
.setDefaultProcessName("${BuildConfig.APPLICATION_ID}:bg")
|
||||||
|
.build()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -87,4 +87,11 @@ object AppConfig {
|
|||||||
const val MSG_MEASURE_CONFIG = 7
|
const val MSG_MEASURE_CONFIG = 7
|
||||||
const val MSG_MEASURE_CONFIG_SUCCESS = 71
|
const val MSG_MEASURE_CONFIG_SUCCESS = 71
|
||||||
const val MSG_MEASURE_CONFIG_CANCEL = 72
|
const val MSG_MEASURE_CONFIG_CANCEL = 72
|
||||||
|
|
||||||
|
// subscription settings
|
||||||
|
const val SUBSCRIPTION_AUTO_UPDATE = "pref_auto_update_subscription"
|
||||||
|
const val SUBSCRIPTION_AUTO_UPDATE_INTERVAL = "pref_auto_update_interval"
|
||||||
|
const val DEFAULT_UPDATE_INTERVAL = "1440" // 24 hours
|
||||||
|
const val UPDATE_TASK_NAME = "subscription-updater"
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
package com.v2ray.ang.dto
|
package com.v2ray.ang.dto
|
||||||
|
|
||||||
data class SubscriptionItem(
|
data class SubscriptionItem(
|
||||||
var remarks: String = "",
|
var remarks: String = "",
|
||||||
var url: String = "",
|
var url: String = "",
|
||||||
var enabled: Boolean = true,
|
var enabled: Boolean = true,
|
||||||
val addedTime: Long = System.currentTimeMillis()) {
|
val addedTime: Long = System.currentTimeMillis(),
|
||||||
}
|
var lastUpdated: Long = -1,
|
||||||
|
var autoUpdate: Boolean = false,
|
||||||
|
val updateInterval: Int? = null,
|
||||||
|
)
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package com.v2ray.ang.service
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.NotificationChannel
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.os.Build
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.core.app.ActivityCompat
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import androidx.work.CoroutineWorker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
import com.v2ray.ang.AppConfig
|
||||||
|
import com.v2ray.ang.R
|
||||||
|
import com.v2ray.ang.extension.toast
|
||||||
|
import com.v2ray.ang.util.AngConfigManager
|
||||||
|
import com.v2ray.ang.util.MmkvManager
|
||||||
|
import com.v2ray.ang.util.Utils
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
|
||||||
|
object SubscriptionUpdater {
|
||||||
|
|
||||||
|
const val notificationChannel = "update-subscription-channel"
|
||||||
|
|
||||||
|
class UpdateTask(context: Context, params: WorkerParameters) :
|
||||||
|
CoroutineWorker(context, params) {
|
||||||
|
|
||||||
|
private val notificationManager = NotificationManagerCompat.from(applicationContext)
|
||||||
|
private val notification =
|
||||||
|
NotificationCompat.Builder(applicationContext, notificationChannel)
|
||||||
|
|
||||||
|
.setWhen(0)
|
||||||
|
.setTicker("Update")
|
||||||
|
.setContentTitle("Subscription Update")
|
||||||
|
.setSmallIcon(R.drawable.ic_stat_name)
|
||||||
|
.setCategory(NotificationCompat.CATEGORY_SERVICE)
|
||||||
|
.setPriority(NotificationCompat.PRIORITY_MIN)
|
||||||
|
|
||||||
|
@SuppressLint("MissingPermission")
|
||||||
|
override suspend fun doWork(): Result {
|
||||||
|
Log.d(AppConfig.ANG_PACKAGE, "start updating subscriptions")
|
||||||
|
|
||||||
|
|
||||||
|
val subs = MmkvManager.decodeSubscriptions().filter { it.second.autoUpdate }
|
||||||
|
|
||||||
|
for (i in subs) {
|
||||||
|
|
||||||
|
val subscription = i.second
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
notification.setChannelId(notificationChannel)
|
||||||
|
val channel =
|
||||||
|
NotificationChannel(
|
||||||
|
notificationChannel,
|
||||||
|
"Subscription Update Service",
|
||||||
|
NotificationManager.IMPORTANCE_MIN
|
||||||
|
)
|
||||||
|
notificationManager.createNotificationChannel(channel)
|
||||||
|
}
|
||||||
|
notificationManager.notify(3, notification.build())
|
||||||
|
Log.d(AppConfig.ANG_PACKAGE, "update: ${subscription.remarks} subscription")
|
||||||
|
val configs = Utils.getUrlContentWithCustomUserAgent(subscription.url)
|
||||||
|
importBatchConfig(configs, i.first)
|
||||||
|
notification.setContentText("Updating ${subscription.remarks}")
|
||||||
|
}
|
||||||
|
notificationManager.cancel(3)
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun importBatchConfig(server: String?, subid: String = "") {
|
||||||
|
|
||||||
|
val append = subid.isNullOrEmpty()
|
||||||
|
|
||||||
|
var count = AngConfigManager.importBatchConfig(server, subid, append)
|
||||||
|
if (count <= 0) {
|
||||||
|
AngConfigManager.importBatchConfig(Utils.decode(server!!), subid, append)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,10 +6,21 @@ import android.text.TextUtils
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.preference.*
|
import androidx.preference.*
|
||||||
|
import androidx.work.Constraints
|
||||||
|
import androidx.work.ExistingPeriodicWorkPolicy
|
||||||
|
import androidx.work.NetworkType
|
||||||
|
import androidx.work.PeriodicWorkRequest
|
||||||
|
import androidx.work.multiprocess.RemoteWorkManager
|
||||||
|
import com.v2ray.ang.AngApplication
|
||||||
import com.v2ray.ang.AppConfig
|
import com.v2ray.ang.AppConfig
|
||||||
import com.v2ray.ang.R
|
import com.v2ray.ang.R
|
||||||
|
import com.v2ray.ang.dto.AngConfig
|
||||||
|
import com.v2ray.ang.service.SubscriptionUpdater
|
||||||
import com.v2ray.ang.util.Utils
|
import com.v2ray.ang.util.Utils
|
||||||
import com.v2ray.ang.viewmodel.SettingsViewModel
|
import com.v2ray.ang.viewmodel.SettingsViewModel
|
||||||
|
import java.sql.Time
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.time.toDuration
|
||||||
|
|
||||||
class SettingsActivity : BaseActivity() {
|
class SettingsActivity : BaseActivity() {
|
||||||
private val settingsViewModel: SettingsViewModel by viewModels()
|
private val settingsViewModel: SettingsViewModel by viewModels()
|
||||||
@@ -31,12 +42,15 @@ class SettingsActivity : BaseActivity() {
|
|||||||
private val fakeDns by lazy { findPreference<CheckBoxPreference>(AppConfig.PREF_FAKE_DNS_ENABLED) }
|
private val fakeDns by lazy { findPreference<CheckBoxPreference>(AppConfig.PREF_FAKE_DNS_ENABLED) }
|
||||||
private val localDnsPort by lazy { findPreference<EditTextPreference>(AppConfig.PREF_LOCAL_DNS_PORT) }
|
private val localDnsPort by lazy { findPreference<EditTextPreference>(AppConfig.PREF_LOCAL_DNS_PORT) }
|
||||||
private val vpnDns by lazy { findPreference<EditTextPreference>(AppConfig.PREF_VPN_DNS) }
|
private val vpnDns by lazy { findPreference<EditTextPreference>(AppConfig.PREF_VPN_DNS) }
|
||||||
|
|
||||||
// val autoRestart by lazy { findPreference(PREF_AUTO_RESTART) as CheckBoxPreference }
|
// val autoRestart by lazy { findPreference(PREF_AUTO_RESTART) as CheckBoxPreference }
|
||||||
private val remoteDns by lazy { findPreference<EditTextPreference>(AppConfig.PREF_REMOTE_DNS) }
|
private val remoteDns by lazy { findPreference<EditTextPreference>(AppConfig.PREF_REMOTE_DNS) }
|
||||||
private val domesticDns by lazy { findPreference<EditTextPreference>(AppConfig.PREF_DOMESTIC_DNS) }
|
private val domesticDns by lazy { findPreference<EditTextPreference>(AppConfig.PREF_DOMESTIC_DNS) }
|
||||||
private val socksPort by lazy { findPreference<EditTextPreference>(AppConfig.PREF_SOCKS_PORT) }
|
private val socksPort by lazy { findPreference<EditTextPreference>(AppConfig.PREF_SOCKS_PORT) }
|
||||||
private val httpPort by lazy { findPreference<EditTextPreference>(AppConfig.PREF_HTTP_PORT) }
|
private val httpPort by lazy { findPreference<EditTextPreference>(AppConfig.PREF_HTTP_PORT) }
|
||||||
private val routingCustom by lazy { findPreference<Preference>(AppConfig.PREF_ROUTING_CUSTOM) }
|
private val routingCustom by lazy { findPreference<Preference>(AppConfig.PREF_ROUTING_CUSTOM) }
|
||||||
|
private val autoUpdateCheck by lazy { findPreference<CheckBoxPreference>(AppConfig.SUBSCRIPTION_AUTO_UPDATE) }
|
||||||
|
private val autoUpdateInterval by lazy { findPreference<EditTextPreference>(AppConfig.SUBSCRIPTION_AUTO_UPDATE_INTERVAL) }
|
||||||
// val licenses: Preference by lazy { findPreference(PREF_LICENSES) }
|
// val licenses: Preference by lazy { findPreference(PREF_LICENSES) }
|
||||||
// val feedback: Preference by lazy { findPreference(PREF_FEEDBACK) }
|
// val feedback: Preference by lazy { findPreference(PREF_FEEDBACK) }
|
||||||
// val tgGroup: Preference by lazy { findPreference(PREF_TG_GROUP) }
|
// val tgGroup: Preference by lazy { findPreference(PREF_TG_GROUP) }
|
||||||
@@ -51,6 +65,24 @@ class SettingsActivity : BaseActivity() {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
autoUpdateCheck?.setOnPreferenceChangeListener { _, newValue ->
|
||||||
|
val value = newValue as Boolean
|
||||||
|
autoUpdateCheck?.isChecked = value
|
||||||
|
autoUpdateInterval?.isEnabled = value
|
||||||
|
autoUpdateInterval?.text?.toLong()?.let {
|
||||||
|
if (newValue) configureUpdateTask(it) else cancelUpdateTask()
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
autoUpdateInterval?.setOnPreferenceChangeListener { _, any ->
|
||||||
|
val nval = any as String
|
||||||
|
autoUpdateInterval?.summary =
|
||||||
|
if (TextUtils.isEmpty(nval) or (nval.toLong() < 15)) AppConfig.DEFAULT_UPDATE_INTERVAL else nval
|
||||||
|
configureUpdateTask(nval.toLong())
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
// licenses.onClick {
|
// licenses.onClick {
|
||||||
// val fragment = LicensesDialogFragment.Builder(act)
|
// val fragment = LicensesDialogFragment.Builder(act)
|
||||||
// .setNotices(R.raw.licenses)
|
// .setNotices(R.raw.licenses)
|
||||||
@@ -92,13 +124,14 @@ class SettingsActivity : BaseActivity() {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
localDns?.setOnPreferenceChangeListener{ _, any ->
|
localDns?.setOnPreferenceChangeListener { _, any ->
|
||||||
updateLocalDns(any as Boolean)
|
updateLocalDns(any as Boolean)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
localDnsPort?.setOnPreferenceChangeListener { _, any ->
|
localDnsPort?.setOnPreferenceChangeListener { _, any ->
|
||||||
val nval = any as String
|
val nval = any as String
|
||||||
localDnsPort?.summary = if (TextUtils.isEmpty(nval)) AppConfig.PORT_LOCAL_DNS else nval
|
localDnsPort?.summary =
|
||||||
|
if (TextUtils.isEmpty(nval)) AppConfig.PORT_LOCAL_DNS else nval
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
vpnDns?.setOnPreferenceChangeListener { _, any ->
|
vpnDns?.setOnPreferenceChangeListener { _, any ->
|
||||||
@@ -125,14 +158,25 @@ class SettingsActivity : BaseActivity() {
|
|||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
val defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity())
|
val defaultSharedPreferences =
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(requireActivity())
|
||||||
updateMode(defaultSharedPreferences.getString(AppConfig.PREF_MODE, "VPN"))
|
updateMode(defaultSharedPreferences.getString(AppConfig.PREF_MODE, "VPN"))
|
||||||
var remoteDnsString = defaultSharedPreferences.getString(AppConfig.PREF_REMOTE_DNS, "")
|
var remoteDnsString = defaultSharedPreferences.getString(AppConfig.PREF_REMOTE_DNS, "")
|
||||||
domesticDns?.summary = defaultSharedPreferences.getString(AppConfig.PREF_DOMESTIC_DNS, "")
|
domesticDns?.summary =
|
||||||
|
defaultSharedPreferences.getString(AppConfig.PREF_DOMESTIC_DNS, "")
|
||||||
|
|
||||||
localDnsPort?.summary = defaultSharedPreferences.getString(AppConfig.PREF_LOCAL_DNS_PORT, AppConfig.PORT_LOCAL_DNS)
|
localDnsPort?.summary = defaultSharedPreferences.getString(
|
||||||
socksPort?.summary = defaultSharedPreferences.getString(AppConfig.PREF_SOCKS_PORT, AppConfig.PORT_SOCKS)
|
AppConfig.PREF_LOCAL_DNS_PORT,
|
||||||
httpPort?.summary = defaultSharedPreferences.getString(AppConfig.PREF_HTTP_PORT, AppConfig.PORT_HTTP)
|
AppConfig.PORT_LOCAL_DNS
|
||||||
|
)
|
||||||
|
socksPort?.summary =
|
||||||
|
defaultSharedPreferences.getString(AppConfig.PREF_SOCKS_PORT, AppConfig.PORT_SOCKS)
|
||||||
|
httpPort?.summary =
|
||||||
|
defaultSharedPreferences.getString(AppConfig.PREF_HTTP_PORT, AppConfig.PORT_HTTP)
|
||||||
|
autoUpdateInterval?.summary = defaultSharedPreferences.getString(
|
||||||
|
AppConfig.SUBSCRIPTION_AUTO_UPDATE_INTERVAL,
|
||||||
|
AppConfig.DEFAULT_UPDATE_INTERVAL
|
||||||
|
)
|
||||||
|
|
||||||
if (TextUtils.isEmpty(remoteDnsString)) {
|
if (TextUtils.isEmpty(remoteDnsString)) {
|
||||||
remoteDnsString = AppConfig.DNS_AGENT
|
remoteDnsString = AppConfig.DNS_AGENT
|
||||||
@@ -141,7 +185,8 @@ class SettingsActivity : BaseActivity() {
|
|||||||
domesticDns?.summary = AppConfig.DNS_DIRECT
|
domesticDns?.summary = AppConfig.DNS_DIRECT
|
||||||
}
|
}
|
||||||
remoteDns?.summary = remoteDnsString
|
remoteDns?.summary = remoteDnsString
|
||||||
vpnDns?.summary = defaultSharedPreferences.getString(AppConfig.PREF_VPN_DNS, remoteDnsString)
|
vpnDns?.summary =
|
||||||
|
defaultSharedPreferences.getString(AppConfig.PREF_VPN_DNS, remoteDnsString)
|
||||||
|
|
||||||
if (TextUtils.isEmpty(localDnsPort?.summary)) {
|
if (TextUtils.isEmpty(localDnsPort?.summary)) {
|
||||||
localDnsPort?.summary = AppConfig.PORT_LOCAL_DNS
|
localDnsPort?.summary = AppConfig.PORT_LOCAL_DNS
|
||||||
@@ -155,17 +200,24 @@ class SettingsActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateMode(mode: String?) {
|
private fun updateMode(mode: String?) {
|
||||||
val defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity())
|
val defaultSharedPreferences =
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(requireActivity())
|
||||||
val vpn = mode == "VPN"
|
val vpn = mode == "VPN"
|
||||||
perAppProxy?.isEnabled = vpn
|
perAppProxy?.isEnabled = vpn
|
||||||
perAppProxy?.isChecked = PreferenceManager.getDefaultSharedPreferences(requireActivity())
|
perAppProxy?.isChecked =
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(requireActivity())
|
||||||
.getBoolean(AppConfig.PREF_PER_APP_PROXY, false)
|
.getBoolean(AppConfig.PREF_PER_APP_PROXY, false)
|
||||||
localDns?.isEnabled = vpn
|
localDns?.isEnabled = vpn
|
||||||
fakeDns?.isEnabled = vpn
|
fakeDns?.isEnabled = vpn
|
||||||
localDnsPort?.isEnabled = vpn
|
localDnsPort?.isEnabled = vpn
|
||||||
vpnDns?.isEnabled = vpn
|
vpnDns?.isEnabled = vpn
|
||||||
if (vpn) {
|
if (vpn) {
|
||||||
updateLocalDns(defaultSharedPreferences.getBoolean(AppConfig.PREF_LOCAL_DNS_ENABLED, false))
|
updateLocalDns(
|
||||||
|
defaultSharedPreferences.getBoolean(
|
||||||
|
AppConfig.PREF_LOCAL_DNS_ENABLED,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,6 +226,33 @@ class SettingsActivity : BaseActivity() {
|
|||||||
localDnsPort?.isEnabled = enabled
|
localDnsPort?.isEnabled = enabled
|
||||||
vpnDns?.isEnabled = !enabled
|
vpnDns?.isEnabled = !enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun configureUpdateTask(interval: Long) {
|
||||||
|
val rw = RemoteWorkManager.getInstance(AngApplication.application)
|
||||||
|
rw.cancelUniqueWork(AppConfig.UPDATE_TASK_NAME)
|
||||||
|
rw.enqueueUniquePeriodicWork(
|
||||||
|
AppConfig.UPDATE_TASK_NAME,
|
||||||
|
ExistingPeriodicWorkPolicy.UPDATE,
|
||||||
|
PeriodicWorkRequest.Builder(
|
||||||
|
SubscriptionUpdater.UpdateTask::class.java,
|
||||||
|
interval,
|
||||||
|
TimeUnit.MINUTES
|
||||||
|
)
|
||||||
|
.apply {
|
||||||
|
setInitialDelay(interval, TimeUnit.MINUTES)
|
||||||
|
}
|
||||||
|
.setConstraints(
|
||||||
|
Constraints(
|
||||||
|
NetworkType.CONNECTED,
|
||||||
|
)
|
||||||
|
).build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun cancelUpdateTask() {
|
||||||
|
val rw = RemoteWorkManager.getInstance(AngApplication.application)
|
||||||
|
rw.cancelUniqueWork(AppConfig.UPDATE_TASK_NAME)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onModeHelpClicked(view: View) {
|
fun onModeHelpClicked(view: View) {
|
||||||
|
|||||||
@@ -5,14 +5,22 @@ import android.text.TextUtils
|
|||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.work.Constraints
|
||||||
|
import androidx.work.ExistingPeriodicWorkPolicy
|
||||||
|
import androidx.work.NetworkType
|
||||||
|
import androidx.work.PeriodicWorkRequest
|
||||||
|
import androidx.work.multiprocess.RemoteWorkManager
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.tencent.mmkv.MMKV
|
import com.tencent.mmkv.MMKV
|
||||||
|
import com.v2ray.ang.AngApplication
|
||||||
import com.v2ray.ang.R
|
import com.v2ray.ang.R
|
||||||
import com.v2ray.ang.databinding.ActivitySubEditBinding
|
import com.v2ray.ang.databinding.ActivitySubEditBinding
|
||||||
import com.v2ray.ang.dto.SubscriptionItem
|
import com.v2ray.ang.dto.SubscriptionItem
|
||||||
import com.v2ray.ang.extension.toast
|
import com.v2ray.ang.extension.toast
|
||||||
|
import com.v2ray.ang.service.SubscriptionUpdater
|
||||||
import com.v2ray.ang.util.MmkvManager
|
import com.v2ray.ang.util.MmkvManager
|
||||||
import com.v2ray.ang.util.Utils
|
import com.v2ray.ang.util.Utils
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class SubEditActivity : BaseActivity() {
|
class SubEditActivity : BaseActivity() {
|
||||||
private lateinit var binding: ActivitySubEditBinding
|
private lateinit var binding: ActivitySubEditBinding
|
||||||
@@ -46,6 +54,7 @@ class SubEditActivity : BaseActivity() {
|
|||||||
binding.etRemarks.text = Utils.getEditable(subItem.remarks)
|
binding.etRemarks.text = Utils.getEditable(subItem.remarks)
|
||||||
binding.etUrl.text = Utils.getEditable(subItem.url)
|
binding.etUrl.text = Utils.getEditable(subItem.url)
|
||||||
binding.chkEnable.isChecked = subItem.enabled
|
binding.chkEnable.isChecked = subItem.enabled
|
||||||
|
binding.autoUpdateCheck.isChecked = subItem.autoUpdate
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +85,7 @@ class SubEditActivity : BaseActivity() {
|
|||||||
subItem.remarks = binding.etRemarks.text.toString()
|
subItem.remarks = binding.etRemarks.text.toString()
|
||||||
subItem.url = binding.etUrl.text.toString()
|
subItem.url = binding.etUrl.text.toString()
|
||||||
subItem.enabled = binding.chkEnable.isChecked
|
subItem.enabled = binding.chkEnable.isChecked
|
||||||
|
subItem.autoUpdate = binding.autoUpdateCheck.isChecked
|
||||||
|
|
||||||
if (TextUtils.isEmpty(subItem.remarks)) {
|
if (TextUtils.isEmpty(subItem.remarks)) {
|
||||||
toast(R.string.sub_setting_remarks)
|
toast(R.string.sub_setting_remarks)
|
||||||
@@ -130,4 +140,5 @@ class SubEditActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
else -> super.onOptionsItemSelected(item)
|
else -> super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -94,6 +94,28 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/layout_margin_top_height"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1.0"
|
||||||
|
android:text="@string/sub_auto_update" />
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatCheckBox
|
||||||
|
android:id="@+id/auto_update_check"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="2dp"
|
||||||
|
android:paddingEnd="6dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|||||||
@@ -183,6 +183,7 @@
|
|||||||
<string name="sub_setting_remarks">remarks</string>
|
<string name="sub_setting_remarks">remarks</string>
|
||||||
<string name="sub_setting_url">Optional URL</string>
|
<string name="sub_setting_url">Optional URL</string>
|
||||||
<string name="sub_setting_enable">enable update</string>
|
<string name="sub_setting_enable">enable update</string>
|
||||||
|
<string name="sub_auto_update">Auto update</string>
|
||||||
<string name="title_sub_update">Update subscription</string>
|
<string name="title_sub_update">Update subscription</string>
|
||||||
<string name="title_ping_all_server">Tcping all configuration</string>
|
<string name="title_ping_all_server">Tcping all configuration</string>
|
||||||
<string name="title_real_ping_all_server">Real delay all configuration</string>
|
<string name="title_real_ping_all_server">Real delay all configuration</string>
|
||||||
|
|||||||
@@ -126,6 +126,21 @@
|
|||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory android:title="Subscription">
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="pref_auto_update_subscription"
|
||||||
|
android:summary="Update your subscriptions automatically with an interval in background"
|
||||||
|
android:title="Automatic update subscriptions" />
|
||||||
|
|
||||||
|
<EditTextPreference
|
||||||
|
android:key="pref_auto_update_interval"
|
||||||
|
android:summary="1440 min"
|
||||||
|
android:inputType="number"
|
||||||
|
android:title="Subscription Update Interval (Minutes)" />
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory android:title="@string/title_ui_settings">
|
<PreferenceCategory android:title="@string/title_ui_settings">
|
||||||
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
|
|||||||
Reference in new issue
Block a user