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]