From 9bee5fbe99e761dc513728db1003298e3507b6e6 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Thu, 20 Mar 2025 15:36:06 +0800 Subject: [PATCH] Refactoring to import custom configuration function Most of the functions have been merged into the existing menu, only the local import function needs to be added. The code is temporarily commented and will be deleted after user testing. --- .../java/com/v2ray/ang/ui/MainActivity.kt | 243 ++++++++++-------- .../com/v2ray/ang/viewmodel/MainViewModel.kt | 63 +++-- V2rayNG/app/src/main/res/menu/menu_main.xml | 48 ++-- .../app/src/main/res/values-ar/strings.xml | 1 + .../app/src/main/res/values-bn/strings.xml | 1 + .../src/main/res/values-bqi-rIR/strings.xml | 1 + .../app/src/main/res/values-fa/strings.xml | 1 + .../app/src/main/res/values-ru/strings.xml | 1 + .../app/src/main/res/values-vi/strings.xml | 1 + .../src/main/res/values-zh-rCN/strings.xml | 1 + .../src/main/res/values-zh-rTW/strings.xml | 1 + V2rayNG/app/src/main/res/values/strings.xml | 1 + 12 files changed, 195 insertions(+), 168 deletions(-) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt index 25618841..5139d45c 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt @@ -8,11 +8,9 @@ import android.net.Uri import android.net.VpnService import android.os.Build import android.os.Bundle -import android.text.TextUtils import android.view.KeyEvent import android.view.Menu import android.view.MenuItem -import android.widget.Toast import androidx.activity.OnBackPressedCallback import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels @@ -38,14 +36,12 @@ import com.v2ray.ang.handler.MigrateManager import com.v2ray.ang.handler.MmkvManager import com.v2ray.ang.helper.SimpleItemTouchHelperCallback import com.v2ray.ang.service.V2RayServiceManager -import com.v2ray.ang.util.HttpUtil import com.v2ray.ang.util.Utils import com.v2ray.ang.viewmodel.MainViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import me.drakeet.support.toast.ToastCompat class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedListener { private val binding by lazy { @@ -87,13 +83,16 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList when (pendingAction) { Action.IMPORT_QR_CODE_CONFIG -> scanQRCodeForConfig.launch(Intent(this, ScannerActivity::class.java)) - Action.IMPORT_QR_CODE_URL -> - scanQRCodeForUrlToCustomConfig.launch(Intent(this, ScannerActivity::class.java)) + +// Action.IMPORT_QR_CODE_URL -> +// scanQRCodeForUrlToCustomConfig.launch(Intent(this, ScannerActivity::class.java)) + Action.READ_CONTENT_FROM_URI -> chooseFileForCustomConfig.launch(Intent.createChooser(Intent(Intent.ACTION_GET_CONTENT).apply { type = "*/*" addCategory(Intent.CATEGORY_OPENABLE) }, getString(R.string.title_file_chooser))) + Action.POST_NOTIFICATIONS -> {} else -> {} } @@ -108,7 +107,8 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList enum class Action { NONE, IMPORT_QR_CODE_CONFIG, - IMPORT_QR_CODE_URL, + + //IMPORT_QR_CODE_URL, READ_CONTENT_FROM_URI, POST_NOTIFICATIONS } @@ -126,11 +126,11 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList } } - private val scanQRCodeForUrlToCustomConfig = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { - if (it.resultCode == RESULT_OK) { - importConfigCustomUrl(it.data?.getStringExtra("SCAN_RESULT")) - } - } +// private val scanQRCodeForUrlToCustomConfig = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { +// if (it.resultCode == RESULT_OK) { +// importConfigCustomUrl(it.data?.getStringExtra("SCAN_RESULT")) +// } +// } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -326,6 +326,11 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList true } + R.id.import_local -> { + importConfigLocal() + true + } + R.id.import_manually_vmess -> { importManually(EConfigType.VMESS.value) true @@ -366,25 +371,25 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList true } - R.id.import_config_custom_clipboard -> { - importConfigCustomClipboard() - true - } - - R.id.import_config_custom_local -> { - importConfigCustomLocal() - true - } - - R.id.import_config_custom_url -> { - importConfigCustomUrlClipboard() - true - } - - R.id.import_config_custom_url_scan -> { - importQRcode(false) - true - } +// R.id.import_config_custom_clipboard -> { +// importConfigCustomClipboard() +// true +// } +// +// R.id.import_config_custom_local -> { +// importConfigCustomLocal() +// true +// } +// +// R.id.import_config_custom_url -> { +// importConfigCustomUrlClipboard() +// true +// } +// +// R.id.import_config_custom_url_scan -> { +// importQRcode(false) +// true +// } R.id.sub_update -> { importConfigViaSub() @@ -517,10 +522,10 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList if (forConfig) { scanQRCodeForConfig.launch(Intent(this, ScannerActivity::class.java)) } else { - scanQRCodeForUrlToCustomConfig.launch(Intent(this, ScannerActivity::class.java)) + //scanQRCodeForUrlToCustomConfig.launch(Intent(this, ScannerActivity::class.java)) } } else { - pendingAction = if (forConfig) Action.IMPORT_QR_CODE_CONFIG else Action.IMPORT_QR_CODE_URL + pendingAction = Action.IMPORT_QR_CODE_CONFIG//if (forConfig) Action.IMPORT_QR_CODE_CONFIG else Action.IMPORT_QR_CODE_URL requestPermissionLauncher.launch(permission) } return true @@ -570,27 +575,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList } } - - private fun importConfigCustomClipboard() - : Boolean { - try { - val configText = Utils.getClipboard(this) - if (TextUtils.isEmpty(configText)) { - toast(R.string.toast_none_data_clipboard) - return false - } - importCustomizeConfig(configText) - return true - } catch (e: Exception) { - e.printStackTrace() - return false - } - } - - /** - * import config from local config file - */ - private fun importConfigCustomLocal(): Boolean { + private fun importConfigLocal(): Boolean { try { showFileChooser() } catch (e: Exception) { @@ -600,47 +585,77 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList return true } - private fun importConfigCustomUrlClipboard() - : Boolean { - try { - val url = Utils.getClipboard(this) - if (TextUtils.isEmpty(url)) { - toast(R.string.toast_none_data_clipboard) - return false - } - return importConfigCustomUrl(url) - } catch (e: Exception) { - e.printStackTrace() - return false - } - } + +// private fun importConfigCustomClipboard() +// : Boolean { +// try { +// val configText = Utils.getClipboard(this) +// if (TextUtils.isEmpty(configText)) { +// toast(R.string.toast_none_data_clipboard) +// return false +// } +// importCustomizeConfig(configText) +// return true +// } catch (e: Exception) { +// e.printStackTrace() +// return false +// } +// } + + /** + * import config from local config file + */ +// private fun importConfigCustomLocal(): Boolean { +// try { +// showFileChooser() +// } catch (e: Exception) { +// e.printStackTrace() +// return false +// } +// return true +// } +// +// private fun importConfigCustomUrlClipboard() +// : Boolean { +// try { +// val url = Utils.getClipboard(this) +// if (TextUtils.isEmpty(url)) { +// toast(R.string.toast_none_data_clipboard) +// return false +// } +// return importConfigCustomUrl(url) +// } catch (e: Exception) { +// e.printStackTrace() +// return false +// } +// } /** * import config from url */ - private fun importConfigCustomUrl(url: String?): Boolean { - try { - if (!Utils.isValidUrl(url)) { - toast(R.string.toast_invalid_url) - return false - } - lifecycleScope.launch(Dispatchers.IO) { - val configText = try { - HttpUtil.getUrlContentWithUserAgent(url) - } catch (e: Exception) { - e.printStackTrace() - "" - } - launch(Dispatchers.Main) { - importCustomizeConfig(configText) - } - } - } catch (e: Exception) { - e.printStackTrace() - return false - } - return true - } +// private fun importConfigCustomUrl(url: String?): Boolean { +// try { +// if (!Utils.isValidUrl(url)) { +// toast(R.string.toast_invalid_url) +// return false +// } +// lifecycleScope.launch(Dispatchers.IO) { +// val configText = try { +// HttpUtil.getUrlContentWithUserAgent(url) +// } catch (e: Exception) { +// e.printStackTrace() +// "" +// } +// launch(Dispatchers.Main) { +// importCustomizeConfig(configText) +// } +// } +// } catch (e: Exception) { +// e.printStackTrace() +// return false +// } +// return true +// } /** * import config from sub @@ -699,7 +714,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList if (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED) { try { contentResolver.openInputStream(uri).use { input -> - importCustomizeConfig(input?.bufferedReader()?.readText()) + importBatchConfig(input?.bufferedReader()?.readText()) } } catch (e: Exception) { e.printStackTrace() @@ -709,28 +724,28 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList } } - /** - * import customize config - */ - private fun importCustomizeConfig(server: String?) { - try { - if (server == null || TextUtils.isEmpty(server)) { - toast(R.string.toast_none_data) - return - } - if (mainViewModel.appendCustomConfigServer(server)) { - mainViewModel.reloadServerList() - toast(R.string.toast_success) - } else { - toast(R.string.toast_failure) - } - //adapter.notifyItemInserted(mainViewModel.serverList.lastIndex) - } catch (e: Exception) { - ToastCompat.makeText(this, "${getString(R.string.toast_malformed_josn)} ${e.cause?.message}", Toast.LENGTH_LONG).show() - e.printStackTrace() - return - } - } +// /** +// * import customize config +// */ +// private fun importCustomizeConfig(server: String?) { +// try { +// if (server == null || TextUtils.isEmpty(server)) { +// toast(R.string.toast_none_data) +// return +// } +// if (mainViewModel.appendCustomConfigServer(server)) { +// mainViewModel.reloadServerList() +// toast(R.string.toast_success) +// } else { +// toast(R.string.toast_failure) +// } +// //adapter.notifyItemInserted(mainViewModel.serverList.lastIndex) +// } catch (e: Exception) { +// ToastCompat.makeText(this, "${getString(R.string.toast_malformed_josn)} ${e.cause?.message}", Toast.LENGTH_LONG).show() +// e.printStackTrace() +// return +// } +// } private fun setTestState(content: String?) { binding.tvTestState.text = content diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/MainViewModel.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/MainViewModel.kt index 22b1d966..290b21a4 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/MainViewModel.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/MainViewModel.kt @@ -19,7 +19,6 @@ import com.v2ray.ang.dto.ProfileItem import com.v2ray.ang.dto.ServersCache import com.v2ray.ang.extension.serializable import com.v2ray.ang.extension.toast -import com.v2ray.ang.fmt.CustomFmt import com.v2ray.ang.handler.AngConfigManager import com.v2ray.ang.handler.MmkvManager import com.v2ray.ang.handler.SettingsManager @@ -89,37 +88,37 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { } } - /** - * Appends a custom configuration server. - * @param server The server configuration to append. - * @return True if the server was successfully appended, false otherwise. - */ - fun appendCustomConfigServer(server: String): Boolean { - if (server.contains("inbounds") - && server.contains("outbounds") - && server.contains("routing") - ) { - try { - val config = CustomFmt.parse(server) ?: return false - config.subscriptionId = subscriptionId - val key = MmkvManager.encodeServerConfig("", config) - MmkvManager.encodeServerRaw(key, server) - serverList.add(0, key) -// val profile = ProfileLiteItem( -// configType = config.configType, -// subscriptionId = config.subscriptionId, -// remarks = config.remarks, -// server = config.getProxyOutbound()?.getServerAddress(), -// serverPort = config.getProxyOutbound()?.getServerPort(), -// ) - serversCache.add(0, ServersCache(key, config)) - return true - } catch (e: Exception) { - e.printStackTrace() - } - } - return false - } +// /** +// * Appends a custom configuration server. +// * @param server The server configuration to append. +// * @return True if the server was successfully appended, false otherwise. +// */ +// fun appendCustomConfigServer(server: String): Boolean { +// if (server.contains("inbounds") +// && server.contains("outbounds") +// && server.contains("routing") +// ) { +// try { +// val config = CustomFmt.parse(server) ?: return false +// config.subscriptionId = subscriptionId +// val key = MmkvManager.encodeServerConfig("", config) +// MmkvManager.encodeServerRaw(key, server) +// serverList.add(0, key) +//// val profile = ProfileLiteItem( +//// configType = config.configType, +//// subscriptionId = config.subscriptionId, +//// remarks = config.remarks, +//// server = config.getProxyOutbound()?.getServerAddress(), +//// serverPort = config.getProxyOutbound()?.getServerPort(), +//// ) +// serversCache.add(0, ServersCache(key, config)) +// return true +// } catch (e: Exception) { +// e.printStackTrace() +// } +// } +// return false +// } /** * Swaps the positions of two servers. diff --git a/V2rayNG/app/src/main/res/menu/menu_main.xml b/V2rayNG/app/src/main/res/menu/menu_main.xml index ce4b16a4..85db881e 100644 --- a/V2rayNG/app/src/main/res/menu/menu_main.xml +++ b/V2rayNG/app/src/main/res/menu/menu_main.xml @@ -20,6 +20,10 @@ android:id="@+id/import_clipboard" android:title="@string/menu_item_import_config_clipboard" app:showAsAction="never" /> + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + حذف التكوين استيراد التكوين من رمز الاستجابة السريعة (QRcode) استيراد التكوين من الحافظة + Import config from locally الكتابة يدويًا [VMess] الكتابة يدويًا [VLESS] الكتابة يدويًا [Shadowsocks] diff --git a/V2rayNG/app/src/main/res/values-bn/strings.xml b/V2rayNG/app/src/main/res/values-bn/strings.xml index 272ee1ea..73192be5 100644 --- a/V2rayNG/app/src/main/res/values-bn/strings.xml +++ b/V2rayNG/app/src/main/res/values-bn/strings.xml @@ -27,6 +27,7 @@ কনফিগারেশন মুছুন QR কোড থেকে কনফিগারেশন আমদানি করুন ক্লিপবোর্ড থেকে কনফিগারেশন আমদানি করুন + Import config from locally ম্যানুয়ালি টাইপ করুন [VMess] ম্যানুয়ালি টাইপ করুন [VLESS] ম্যানুয়ালি টাইপ করুন [Shadowsocks] diff --git a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml index 7e31d20f..37159984 100644 --- a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml +++ b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml @@ -27,6 +27,7 @@ پاک کردن کانفیگ و من ٱووردن کانفیگ ز QRcode و من ٱووردن کانفیگ ز کلیپ بورد + Import config from locally هؽل دستی[VMess] هؽل دستی[VLESS] هؽل دستی[Shadowsocks] diff --git a/V2rayNG/app/src/main/res/values-fa/strings.xml b/V2rayNG/app/src/main/res/values-fa/strings.xml index 7e795239..a3cae007 100644 --- a/V2rayNG/app/src/main/res/values-fa/strings.xml +++ b/V2rayNG/app/src/main/res/values-fa/strings.xml @@ -27,6 +27,7 @@ حذف کانفیگ کانفیگ را از QRcode وارد کنید کانفیگ را از کلیپ ‌بورد وارد کنید + Import config from locally تایپ دستی[VMESS] تایپ دستی[VLESS] تایپ دستی[SHADOWSOCKS] diff --git a/V2rayNG/app/src/main/res/values-ru/strings.xml b/V2rayNG/app/src/main/res/values-ru/strings.xml index 52d79a6f..c50432ae 100644 --- a/V2rayNG/app/src/main/res/values-ru/strings.xml +++ b/V2rayNG/app/src/main/res/values-ru/strings.xml @@ -26,6 +26,7 @@ Удалить профиль Импорт из QR-кода Импорт из буфера обмена + Import config from locally Ручной ввод VMess Ручной ввод VLESS Ручной ввод Shadowsocks diff --git a/V2rayNG/app/src/main/res/values-vi/strings.xml b/V2rayNG/app/src/main/res/values-vi/strings.xml index f0acddf4..c7666524 100644 --- a/V2rayNG/app/src/main/res/values-vi/strings.xml +++ b/V2rayNG/app/src/main/res/values-vi/strings.xml @@ -26,6 +26,7 @@ Xoá cấu hình Nhập cấu hình từ mã QR Nhập cấu hình từ Clipboard + Import config from locally Nhập thủ công [VMess] Nhập thủ công [VLESS] Nhập thủ công [ShadowSocks] diff --git a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml index 3542d89f..ef2813e4 100644 --- a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml @@ -26,6 +26,7 @@ 删除配置 扫描二维码 从剪贴板导入 + 从本地导入 手动输入[VMess] 手动输入[VLESS] 手动输入[Shadowsocks] diff --git a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml index 05fa03b5..ecdb5d3d 100644 --- a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml @@ -26,6 +26,7 @@ 刪除設定 從 QR Code 匯入設定 從剪貼簿匯入設定 + 從本地匯入 手動鍵入 [VMess] 手動鍵入 [VLESS] 手動鍵入 [Shadowsocks] diff --git a/V2rayNG/app/src/main/res/values/strings.xml b/V2rayNG/app/src/main/res/values/strings.xml index efdee8df..25aba52b 100644 --- a/V2rayNG/app/src/main/res/values/strings.xml +++ b/V2rayNG/app/src/main/res/values/strings.xml @@ -27,6 +27,7 @@ Delete config Import config from QRcode Import config from Clipboard + Import config from locally Type manually[VMess] Type manually[VLESS] Type manually[Shadowsocks]