diff --git a/README.md b/README.md index d387b31ee..b23e5e745 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ A V2Ray client for Android, support [Xray core](https://github.com/XTLS/Xray-core) and [v2fly core](https://github.com/v2fly/v2ray-core) -[![API](https://img.shields.io/badge/API-17%2B-yellow.svg?style=flat)](https://developer.android.com/about/versions/jelly-bean#android-4.2) -[![Kotlin Version](https://img.shields.io/badge/Kotlin-1.5.10-blue.svg)](https://kotlinlang.org) +[![API](https://img.shields.io/badge/API-21%2B-yellow.svg?style=flat)](https://developer.android.com/about/versions/lollipop) +[![Kotlin Version](https://img.shields.io/badge/Kotlin-1.6.10-blue.svg)](https://kotlinlang.org) [![GitHub commit activity](https://img.shields.io/github/commit-activity/m/2dust/v2rayNG)](https://github.com/2dust/v2rayNG/commits/master) [![CodeFactor](https://www.codefactor.io/repository/github/2dust/v2rayng/badge)](https://www.codefactor.io/repository/github/2dust/v2rayng) [![GitHub Releases](https://img.shields.io/github/downloads/2dust/v2rayNG/latest/total?logo=github)](https://github.com/2dust/v2rayNG/releases) @@ -16,15 +16,12 @@ A V2Ray client for Android, support [Xray core](https://github.com/XTLS/Xray-cor ### Usage #### Geoip and Geosite -v2rayNG release already embedded domain file `geoip.dat` and `geosite.dat`. However it is (probably) not the latest and not the most complete list. -For power user, the embedded files can be easily replaced with the following steps: -1. Launch v2rayNG (v1.4.9+) -2. Find existing geoip.dat and geosite.dat in `Android/data/com.v2ray.ang/files/assets` (path may differ on some Android device) -3. Replace them with the latest [domain list](https://github.com/v2fly/domain-list-community) and [ip list](https://github.com/v2fly/geoip) -4. Enhanced version can be found in this [repo](https://github.com/Loyalsoldier/v2ray-rules-dat) (recommend to use `geosite:geolocation-!cn` for proxy dns and routing) -5. It is also possible to use third party dat file in the same folder, like [h2y](https://guide.v2fly.org/routing/sitedata.html#%E5%A4%96%E7%BD%AE%E7%9A%84%E5%9F%9F%E5%90%8D%E6%96%87%E4%BB%B6) +- geoip.dat and geosite.dat files are in `Android/data/com.v2ray.ang/files/assets` (path may differ on some Android device) +- download feature will get enhanced version in this [repo](https://github.com/Loyalsoldier/v2ray-rules-dat) (Note it need a working proxy) +- latest official [domain list](https://github.com/v2fly/domain-list-community) and [ip list](https://github.com/v2fly/geoip) can be imported manually +- possible to use third party dat file in the same folder, like [h2y](https://guide.v2fly.org/routing/sitedata.html#%E5%A4%96%E7%BD%AE%E7%9A%84%E5%9F%9F%E5%90%8D%E6%96%87%E4%BB%B6) -#### See more in our [wiki](https://github.com/2dust/v2rayNG/wiki) +### More in our [wiki](https://github.com/2dust/v2rayNG/wiki) ### Development guide @@ -32,4 +29,4 @@ Android project under V2rayNG folder can be compiled directly in Android Studio, The aar can be compiled from the Golang project under AndroidLibV2rayLite folder. For a quick start, read guide for [Go Mobile](https://github.com/golang/go/wiki/Mobile) and [Makefiles for Go Developers](https://tutorialedge.net/golang/makefiles-for-go-developers/) -v2rayNG can run on Android Emulators, with minimum Android 5.0 +v2rayNG can run on Android Emulators. But VPN mode will not work if system don't support it, like Windows 11 WSA diff --git a/V2rayNG/app/build.gradle b/V2rayNG/app/build.gradle index 2fc17ae50..beeb64631 100644 --- a/V2rayNG/app/build.gradle +++ b/V2rayNG/app/build.gradle @@ -13,7 +13,7 @@ android { defaultConfig { applicationId "com.v2ray.ang" - minSdkVersion 17 + minSdkVersion 21 targetSdkVersion Integer.parseInt("$targetSdkVer") multiDexEnabled true versionCode 212 @@ -59,7 +59,9 @@ android { android.applicationVariants.all { variant -> // assign different version code for each output variant.outputs.each { output -> - output.versionCodeOverride = + output.outputFileName = "v2rayNG_" + variant.versionName + "_" + output.getFilter(com.android.build.OutputFile.ABI) + ".apk" + + output.versionCodeOverride = project.ext.versionCodes.get(output.getFilter(com.android.build.OutputFile.ABI), 0) * 1000000 + android.defaultConfig.versionCode } @@ -72,13 +74,13 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.aar', '*.jar'], exclude: []) - testImplementation 'junit:junit:4.13' + testImplementation 'junit:junit:4.13.2' // Androidx - implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation 'androidx.constraintlayout:constraintlayout:2.1.3' implementation "androidx.legacy:legacy-support-v4:1.0.0" - implementation "androidx.appcompat:appcompat:1.3.0" - implementation "com.google.android.material:material:1.4.0" + implementation "androidx.appcompat:appcompat:1.4.1" + implementation "com.google.android.material:material:1.5.0" implementation "androidx.cardview:cardview:1.0.0" implementation "androidx.preference:preference:1.0.0" implementation "androidx.recyclerview:recyclerview:1.2.1" @@ -86,17 +88,16 @@ dependencies { implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01' // Androidx ktx - implementation 'androidx.activity:activity-ktx:1.2.4' + implementation 'androidx.activity:activity-ktx:1.4.0' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' - implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1' + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.1' //kotlin - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2" - implementation 'com.tencent:mmkv-static:1.2.7' + implementation 'com.tencent:mmkv-static:1.2.12' implementation 'com.google.code.gson:gson:2.8.6' implementation 'io.reactivex:rxjava:1.3.4' implementation 'io.reactivex:rxandroid:1.2.1' @@ -105,15 +106,18 @@ dependencies { implementation 'me.dm7.barcodescanner:zxing:1.9.8' implementation 'com.github.jorgecastilloprz:fabprogresscircle:1.01@aar' implementation 'me.drakeet.support:toastcompat:1.1.0' - implementation 'com.blacksquircle.ui:editorkit:2.0.0' - implementation 'com.blacksquircle.ui:language-json:2.0.0' + implementation 'com.blacksquircle.ui:editorkit:2.1.1' + implementation 'com.blacksquircle.ui:language-base:2.1.1' + implementation 'com.blacksquircle.ui:language-json:2.1.1' } buildscript { repositories { google() - jcenter() + mavenCentral() maven { url 'https://maven.google.com' } + maven { url 'https://jitpack.io' } + jcenter() } dependencies { classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlinVersion" diff --git a/V2rayNG/app/src/main/AndroidManifest.xml b/V2rayNG/app/src/main/AndroidManifest.xml index 898497374..2eb313f15 100644 --- a/V2rayNG/app/src/main/AndroidManifest.xml +++ b/V2rayNG/app/src/main/AndroidManifest.xml @@ -28,17 +28,17 @@ - - + android:theme="@style/AppTheme" + android:usesCleartextTraffic="true" + tools:targetApi="m"> @@ -59,24 +59,40 @@ android:resource="@xml/shortcuts" /> - - - - - + + + + - - - - + + + - @@ -135,7 +155,9 @@ - diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/extension/_Ext.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/extension/_Ext.kt index 4d317e675..e238ff274 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/extension/_Ext.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/extension/_Ext.kt @@ -15,13 +15,13 @@ import java.net.URLConnection val Context.v2RayApplication: AngApplication get() = applicationContext as AngApplication -inline fun Context.toast(message: Int): Toast = ToastCompat +fun Context.toast(message: Int): Toast = ToastCompat .makeText(this, message, Toast.LENGTH_SHORT) .apply { show() } -inline fun Context.toast(message: CharSequence): Toast = ToastCompat +fun Context.toast(message: CharSequence): Toast = ToastCompat .makeText(this, message, Toast.LENGTH_SHORT) .apply { show() diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/receiver/WidgetProvider.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/receiver/WidgetProvider.kt index 20259d4e3..826bf24fd 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/receiver/WidgetProvider.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/receiver/WidgetProvider.kt @@ -6,6 +6,7 @@ import android.appwidget.AppWidgetProvider import android.content.ComponentName import android.content.Context import android.content.Intent +import android.os.Build import android.widget.RemoteViews import com.v2ray.ang.R import com.v2ray.ang.AppConfig @@ -21,16 +22,33 @@ class WidgetProvider : AppWidgetProvider() { updateWidgetBackground(context, appWidgetManager, appWidgetIds, V2RayServiceManager.v2rayPoint.isRunning) } + private fun updateWidgetBackground(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray, isRunning: Boolean) { val remoteViews = RemoteViews(context.packageName, R.layout.widget_switch) val intent = Intent(context, WidgetProvider::class.java) intent.action = AppConfig.BROADCAST_ACTION_WIDGET_CLICK - val pendingIntent = PendingIntent.getBroadcast(context, R.id.layout_switch, intent, PendingIntent.FLAG_UPDATE_CURRENT) + val pendingIntent = PendingIntent.getBroadcast( + context, + R.id.layout_switch, + intent, + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT + } else { + PendingIntent.FLAG_UPDATE_CURRENT + }) remoteViews.setOnClickPendingIntent(R.id.layout_switch, pendingIntent) if (isRunning) { - remoteViews.setInt(R.id.layout_switch, "setBackgroundResource", R.drawable.ic_rounded_corner_theme) + remoteViews.setInt( + R.id.layout_switch, + "setBackgroundResource", + R.drawable.ic_rounded_corner_theme + ) } else { - remoteViews.setInt(R.id.layout_switch, "setBackgroundResource", R.drawable.ic_rounded_corner_grey) + remoteViews.setInt( + R.id.layout_switch, + "setBackgroundResource", + R.drawable.ic_rounded_corner_grey + ) } for (appWidgetId in appWidgetIds) { 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 cf44bfa2f..8ee397925 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 @@ -237,7 +237,11 @@ object V2RayServiceManager { val startMainIntent = Intent(service, MainActivity::class.java) val contentPendingIntent = PendingIntent.getActivity(service, NOTIFICATION_PENDING_INTENT_CONTENT, startMainIntent, - PendingIntent.FLAG_UPDATE_CURRENT) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT + } else { + PendingIntent.FLAG_UPDATE_CURRENT + }) val stopV2RayIntent = Intent(AppConfig.BROADCAST_ACTION_SERVICE) stopV2RayIntent.`package` = ANG_PACKAGE @@ -245,7 +249,11 @@ object V2RayServiceManager { val stopV2RayPendingIntent = PendingIntent.getBroadcast(service, NOTIFICATION_PENDING_INTENT_STOP_V2RAY, stopV2RayIntent, - PendingIntent.FLAG_UPDATE_CURRENT) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT + } else { + PendingIntent.FLAG_UPDATE_CURRENT + }) val channelId = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/V2RayVpnService.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/V2RayVpnService.kt index 586c5c00d..240e6db8a 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/V2RayVpnService.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/service/V2RayVpnService.kt @@ -132,8 +132,7 @@ class V2RayVpnService : VpnService(), ServiceControl { builder.setSession(V2RayServiceManager.currentConfig?.remarks.orEmpty()) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && - settingsStorage?.decodeBool(AppConfig.PREF_PER_APP_PROXY) == true) { + if (settingsStorage?.decodeBool(AppConfig.PREF_PER_APP_PROXY) == true) { val apps = settingsStorage?.decodeStringSet(AppConfig.PREF_PER_APP_PROXY_SET) val bypassApps = settingsStorage?.decodeBool(AppConfig.PREF_BYPASS_APPS) ?: false apps?.forEach { diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/LogcatActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/LogcatActivity.kt index 146884fa9..7128010f7 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/LogcatActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/LogcatActivity.kt @@ -70,7 +70,7 @@ class LogcatActivity : BaseActivity() { } } - override fun onCreateOptionsMenu(menu: Menu?): Boolean { + override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_logcat, menu) return super.onCreateOptionsMenu(menu) } 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 09a6dff9d..c876fe3ea 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 @@ -169,7 +169,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList super.onPause() } - override fun onCreateOptionsMenu(menu: Menu?): Boolean { + override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_main, menu) return true } diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/PerAppProxyActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/PerAppProxyActivity.kt index 003e06ddd..435bd1e7b 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/PerAppProxyActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/PerAppProxyActivity.kt @@ -188,7 +188,7 @@ class PerAppProxyActivity : BaseActivity() { } } - override fun onCreateOptionsMenu(menu: Menu?): Boolean { + override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_bypass_list, menu) return super.onCreateOptionsMenu(menu) } diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/RoutingSettingsFragment.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/RoutingSettingsFragment.kt index 37d1788a4..70269460d 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/RoutingSettingsFragment.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/RoutingSettingsFragment.kt @@ -4,33 +4,38 @@ import android.Manifest import android.app.Activity.RESULT_OK import android.content.Intent import android.os.Bundle +import android.text.TextUtils import androidx.fragment.app.Fragment import androidx.preference.PreferenceManager import android.view.* -import com.v2ray.ang.R -import com.v2ray.ang.util.Utils import kotlinx.android.synthetic.main.fragment_routing_settings.* import android.view.MenuInflater import androidx.activity.result.contract.ActivityResultContracts import com.tbruyelle.rxpermissions.RxPermissions import com.v2ray.ang.AppConfig +import com.v2ray.ang.R +import com.v2ray.ang.databinding.FragmentRoutingSettingsBinding import com.v2ray.ang.extension.toast +import com.v2ray.ang.extension.v2RayApplication +import com.v2ray.ang.util.Utils import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import java.net.URL class RoutingSettingsFragment : Fragment() { + private lateinit var binding: FragmentRoutingSettingsBinding companion object { private const val routing_arg = "routing_arg" } - val defaultSharedPreferences by lazy { PreferenceManager.getDefaultSharedPreferences(context) } + val defaultSharedPreferences by lazy { PreferenceManager.getDefaultSharedPreferences(requireContext()) } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { // Inflate the layout for this fragment - return inflater.inflate(R.layout.fragment_routing_settings, container, false) + binding = FragmentRoutingSettingsBinding.inflate(layoutInflater) + return binding.root// inflater.inflate(R.layout.fragment_routing_settings, container, false) } fun newInstance(arg: String): Fragment { @@ -45,7 +50,7 @@ class RoutingSettingsFragment : Fragment() { super.onViewCreated(view, savedInstanceState) val content = defaultSharedPreferences.getString(requireArguments().getString(routing_arg), "") - et_routing_content.text = Utils.getEditable(content!!) + binding.etRoutingContent.text = Utils.getEditable(content!!) setHasOptionsMenu(true) } @@ -63,7 +68,7 @@ class RoutingSettingsFragment : Fragment() { true } R.id.del_routing -> { - et_routing_content.text = null + binding.etRoutingContent.text = null true } R.id.scan_replace -> { @@ -81,6 +86,12 @@ class RoutingSettingsFragment : Fragment() { else -> super.onOptionsItemSelected(item) } + private fun saveRouting() { + val content = binding.etRoutingContent.text.toString() + defaultSharedPreferences.edit().putString(requireArguments().getString(routing_arg), content).apply() + activity?.toast(R.string.toast_success) + } + fun scanQRcode(forReplace: Boolean): Boolean { // try { // startActivityForResult(Intent("com.google.zxing.client.android.SCAN") @@ -105,14 +116,14 @@ class RoutingSettingsFragment : Fragment() { private val scanQRCodeForReplace = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { if (it.resultCode == RESULT_OK) { val content = it.data?.getStringExtra("SCAN_RESULT") - et_routing_content.text = Utils.getEditable(content!!) + binding.etRoutingContent.text = Utils.getEditable(content!!) } } private val scanQRCodeForAppend = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { if (it.resultCode == RESULT_OK) { val content = it.data?.getStringExtra("SCAN_RESULT") - et_routing_content.text = Utils.getEditable("${et_routing_content.text},$content") + binding.etRoutingContent.text = Utils.getEditable("${binding.etRoutingContent.text},$content") } } @@ -139,8 +150,14 @@ class RoutingSettingsFragment : Fragment() { "" } launch(Dispatchers.Main) { - et_routing_content.text = Utils.getEditable(content) - activity?.toast(R.string.toast_success) + val routingList = if (TextUtils.isEmpty(content)) { + Utils.readTextFromAssets(activity?.v2RayApplication!!, "custom_routing_$tag") + } else { + content + } + binding.etRoutingContent.text = Utils.getEditable(routingList) + saveRouting() + //toast(R.string.toast_success) } } return true diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ScannerActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ScannerActivity.kt index 03fb791ef..e4982d837 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ScannerActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ScannerActivity.kt @@ -63,7 +63,7 @@ class ScannerActivity : BaseActivity(), ZXingScannerView.ResultHandler { finish() } - override fun onCreateOptionsMenu(menu: Menu?): Boolean { + override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_scanner, menu) return true } diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ServerActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ServerActivity.kt index 17fd859ae..a0139dffb 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ServerActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ServerActivity.kt @@ -315,10 +315,10 @@ class ServerActivity : BaseActivity() { return true } - override fun onCreateOptionsMenu(menu: Menu?): Boolean { + override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.action_server, menu) - val delButton = menu?.findItem(R.id.del_config) - val saveButton = menu?.findItem(R.id.save_config) + val delButton = menu.findItem(R.id.del_config) + val saveButton = menu.findItem(R.id.save_config) if (editGuid.isNotEmpty()) { if (isRunning) { diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ServerCustomConfigActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ServerCustomConfigActivity.kt index e445b7444..a38c1783a 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ServerCustomConfigActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ServerCustomConfigActivity.kt @@ -113,10 +113,10 @@ class ServerCustomConfigActivity : BaseActivity() { return true } - override fun onCreateOptionsMenu(menu: Menu?): Boolean { + override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.action_server, menu) - val delButton = menu?.findItem(R.id.del_config) - val saveButton = menu?.findItem(R.id.save_config) + val delButton = menu.findItem(R.id.del_config) + val saveButton = menu.findItem(R.id.save_config) if (editGuid.isNotEmpty()) { if (isRunning) { 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 87226b082..c32d74cc8 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 @@ -203,7 +203,7 @@ class SettingsActivity : BaseActivity() { override fun onStart() { super.onStart() - val defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(activity) + val defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity()) updateMode(defaultSharedPreferences.getString(AppConfig.PREF_MODE, "VPN")) var remoteDnsString = defaultSharedPreferences.getString(AppConfig.PREF_REMOTE_DNS, "") domesticDns.summary = defaultSharedPreferences.getString(AppConfig.PREF_DOMESTIC_DNS, "") @@ -222,10 +222,10 @@ class SettingsActivity : BaseActivity() { } private fun updateMode(mode: String?) { - val defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(activity) + val defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity()) val vpn = mode == "VPN" perAppProxy.isEnabled = vpn - perAppProxy.isChecked = PreferenceManager.getDefaultSharedPreferences(activity) + perAppProxy.isChecked = PreferenceManager.getDefaultSharedPreferences(requireActivity()) .getBoolean(AppConfig.PREF_PER_APP_PROXY, false) localDns?.isEnabled = vpn fakeDns?.isEnabled = vpn diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SubEditActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SubEditActivity.kt index dbc048951..f7b1c30a5 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SubEditActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SubEditActivity.kt @@ -106,10 +106,10 @@ class SubEditActivity : BaseActivity() { return true } - override fun onCreateOptionsMenu(menu: Menu?): Boolean { + override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.action_server, menu) - del_config = menu?.findItem(R.id.del_config) - save_config = menu?.findItem(R.id.save_config) + del_config = menu.findItem(R.id.del_config) + save_config = menu.findItem(R.id.save_config) if (editSubId.isEmpty()) { del_config?.isVisible = false diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SubSettingActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SubSettingActivity.kt index 32abe229c..a00307306 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SubSettingActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SubSettingActivity.kt @@ -37,10 +37,10 @@ class SubSettingActivity : BaseActivity() { adapter.notifyDataSetChanged() } - override fun onCreateOptionsMenu(menu: Menu?): Boolean { + override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.action_sub_setting, menu) - menu?.findItem(R.id.del_config)?.isVisible = false - menu?.findItem(R.id.save_config)?.isVisible = false + menu.findItem(R.id.del_config)?.isVisible = false + menu.findItem(R.id.save_config)?.isVisible = false return super.onCreateOptionsMenu(menu) } diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/TaskerActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/TaskerActivity.kt index 8ee9d68f3..1fff3fbc4 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/TaskerActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/TaskerActivity.kt @@ -95,9 +95,9 @@ class TaskerActivity : BaseActivity() { finish() } - override fun onCreateOptionsMenu(menu: Menu?): Boolean { + override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.action_server, menu) - val del_config = menu?.findItem(R.id.del_config) + val del_config = menu.findItem(R.id.del_config) del_config?.isVisible = false return super.onCreateOptionsMenu(menu) } diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt index 74844498e..8888ecb06 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt @@ -167,7 +167,7 @@ object AngConfigManager { } //maybe sub - if (str.startsWith(HTTP_PROTOCOL) || str.startsWith(HTTPS_PROTOCOL)) { + if (TextUtils.isEmpty(subid) && (str.startsWith(HTTP_PROTOCOL) || str.startsWith(HTTPS_PROTOCOL))) { MmkvManager.importUrlAsSubscription(str) return 0 } diff --git a/V2rayNG/app/src/main/res/color-v21/color_highlight_material.xml b/V2rayNG/app/src/main/res/color/color_highlight_material.xml similarity index 100% rename from V2rayNG/app/src/main/res/color-v21/color_highlight_material.xml rename to V2rayNG/app/src/main/res/color/color_highlight_material.xml diff --git a/V2rayNG/app/src/main/res/layout/preference_with_help_link.xml b/V2rayNG/app/src/main/res/layout/preference_with_help_link.xml index da232f935..ec6e6423a 100644 --- a/V2rayNG/app/src/main/res/layout/preference_with_help_link.xml +++ b/V2rayNG/app/src/main/res/layout/preference_with_help_link.xml @@ -1,9 +1,11 @@