├── .github ├── ISSUE_TEMPLATE │ ├── bug_cn.md │ └── config.yml └── workflows │ ├── build.yml │ └── fastlane.yml ├── .gitignore ├── .gitmodules ├── CR.md ├── LICENSE ├── README.md ├── V2rayNG ├── app │ ├── build.gradle.kts │ ├── proguard-rules.pro │ └── src │ │ ├── dev │ │ └── res │ │ │ └── values │ │ │ └── strings.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── assets │ │ │ ├── custom_routing_black │ │ │ ├── custom_routing_global │ │ │ ├── custom_routing_white │ │ │ ├── custom_routing_white_iran │ │ │ ├── open_source_licenses.html │ │ │ ├── proxy_packagename.txt │ │ │ └── v2ray_config.json │ │ ├── ic_launcher-web.png │ │ ├── java │ │ │ └── com │ │ │ │ └── v2ray │ │ │ │ └── ang │ │ │ │ ├── AngApplication.kt │ │ │ │ ├── AppConfig.kt │ │ │ │ ├── dto │ │ │ │ ├── AppInfo.kt │ │ │ │ ├── AssetUrlItem.kt │ │ │ │ ├── CheckUpdateResult.kt │ │ │ │ ├── ConfigResult.kt │ │ │ │ ├── EConfigType.kt │ │ │ │ ├── GitHubRelease.kt │ │ │ │ ├── Hysteria2Bean.kt │ │ │ │ ├── IPAPIInfo.kt │ │ │ │ ├── Language.kt │ │ │ │ ├── NetworkType.kt │ │ │ │ ├── ProfileItem.kt │ │ │ │ ├── RoutingType.kt │ │ │ │ ├── RulesetItem.kt │ │ │ │ ├── ServerAffiliationInfo.kt │ │ │ │ ├── ServerConfig.kt │ │ │ │ ├── ServersCache.kt │ │ │ │ ├── SubscriptionItem.kt │ │ │ │ ├── V2rayConfig.kt │ │ │ │ └── VmessQRCode.kt │ │ │ │ ├── extension │ │ │ │ └── _Ext.kt │ │ │ │ ├── fmt │ │ │ │ ├── CustomFmt.kt │ │ │ │ ├── FmtBase.kt │ │ │ │ ├── HttpFmt.kt │ │ │ │ ├── Hysteria2Fmt.kt │ │ │ │ ├── ShadowsocksFmt.kt │ │ │ │ ├── SocksFmt.kt │ │ │ │ ├── TrojanFmt.kt │ │ │ │ ├── VlessFmt.kt │ │ │ │ ├── VmessFmt.kt │ │ │ │ └── WireguardFmt.kt │ │ │ │ ├── handler │ │ │ │ ├── AngConfigManager.kt │ │ │ │ ├── MigrateManager.kt │ │ │ │ ├── MmkvManager.kt │ │ │ │ ├── SettingsManager.kt │ │ │ │ ├── SpeedtestManager.kt │ │ │ │ ├── UpdateCheckerManager.kt │ │ │ │ └── V2rayConfigManager.kt │ │ │ │ ├── helper │ │ │ │ ├── CustomDividerItemDecoration.kt │ │ │ │ ├── ItemTouchHelperAdapter.kt │ │ │ │ ├── ItemTouchHelperViewHolder.kt │ │ │ │ └── SimpleItemTouchHelperCallback.kt │ │ │ │ ├── plugin │ │ │ │ ├── NativePlugin.kt │ │ │ │ ├── Plugin.kt │ │ │ │ ├── PluginContract.kt │ │ │ │ ├── PluginList.kt │ │ │ │ ├── PluginManager.kt │ │ │ │ └── ResolvedPlugin.kt │ │ │ │ ├── receiver │ │ │ │ ├── BootReceiver.kt │ │ │ │ ├── TaskerReceiver.kt │ │ │ │ └── WidgetProvider.kt │ │ │ │ ├── service │ │ │ │ ├── NotificationService.kt │ │ │ │ ├── ProcessService.kt │ │ │ │ ├── QSTileService.kt │ │ │ │ ├── ServiceControl.kt │ │ │ │ ├── SubscriptionUpdater.kt │ │ │ │ ├── V2RayProxyOnlyService.kt │ │ │ │ ├── V2RayServiceManager.kt │ │ │ │ ├── V2RayTestService.kt │ │ │ │ └── V2RayVpnService.kt │ │ │ │ ├── ui │ │ │ │ ├── AboutActivity.kt │ │ │ │ ├── BaseActivity.kt │ │ │ │ ├── CheckUpdateActivity.kt │ │ │ │ ├── FragmentAdapter.kt │ │ │ │ ├── LogcatActivity.kt │ │ │ │ ├── LogcatRecyclerAdapter.kt │ │ │ │ ├── MainActivity.kt │ │ │ │ ├── MainRecyclerAdapter.kt │ │ │ │ ├── PerAppProxyActivity.kt │ │ │ │ ├── PerAppProxyAdapter.kt │ │ │ │ ├── RoutingEditActivity.kt │ │ │ │ ├── RoutingSettingActivity.kt │ │ │ │ ├── RoutingSettingRecyclerAdapter.kt │ │ │ │ ├── ScScannerActivity.kt │ │ │ │ ├── ScSwitchActivity.kt │ │ │ │ ├── ScannerActivity.kt │ │ │ │ ├── ServerActivity.kt │ │ │ │ ├── ServerCustomConfigActivity.kt │ │ │ │ ├── SettingsActivity.kt │ │ │ │ ├── SubEditActivity.kt │ │ │ │ ├── SubSettingActivity.kt │ │ │ │ ├── SubSettingRecyclerAdapter.kt │ │ │ │ ├── TaskerActivity.kt │ │ │ │ ├── UrlSchemeActivity.kt │ │ │ │ ├── UserAssetActivity.kt │ │ │ │ └── UserAssetUrlActivity.kt │ │ │ │ ├── util │ │ │ │ ├── AppManagerUtil.kt │ │ │ │ ├── HttpUtil.kt │ │ │ │ ├── JsonUtil.kt │ │ │ │ ├── MessageUtil.kt │ │ │ │ ├── MyContextWrapper.kt │ │ │ │ ├── PluginUtil.kt │ │ │ │ ├── QRCodeDecoder.kt │ │ │ │ ├── Utils.kt │ │ │ │ └── ZipUtil.kt │ │ │ │ └── viewmodel │ │ │ │ ├── MainViewModel.kt │ │ │ │ └── SettingsViewModel.kt │ │ └── res │ │ │ ├── color │ │ │ └── color_highlight_material.xml │ │ │ ├── drawable-hdpi │ │ │ ├── ic_stat_direct.png │ │ │ ├── ic_stat_name.png │ │ │ └── ic_stat_proxy.png │ │ │ ├── drawable-mdpi │ │ │ ├── ic_stat_direct.png │ │ │ ├── ic_stat_name.png │ │ │ ├── ic_stat_name_black.png │ │ │ └── ic_stat_proxy.png │ │ │ ├── drawable-night │ │ │ ├── ic_about_24dp.xml │ │ │ ├── ic_action_done.xml │ │ │ ├── ic_add_24dp.xml │ │ │ ├── ic_backup_24dp.xml │ │ │ ├── ic_check_update_24dp.xml │ │ │ ├── ic_cloud_download_24dp.xml │ │ │ ├── ic_copy.xml │ │ │ ├── ic_delete_24dp.xml │ │ │ ├── ic_description_24dp.xml │ │ │ ├── ic_edit_24dp.xml │ │ │ ├── ic_fab_check.xml │ │ │ ├── ic_feedback_24dp.xml │ │ │ ├── ic_file_24dp.xml │ │ │ ├── ic_image_24dp.xml │ │ │ ├── ic_lock_24dp.xml │ │ │ ├── ic_logcat_24dp.xml │ │ │ ├── ic_more_vert_24dp.xml │ │ │ ├── ic_outline_filter_alt_24.xml │ │ │ ├── ic_per_apps_24dp.xml │ │ │ ├── ic_play_24dp.xml │ │ │ ├── ic_privacy_24dp.xml │ │ │ ├── ic_promotion_24dp.xml │ │ │ ├── ic_restore_24dp.xml │ │ │ ├── ic_routing_24dp.xml │ │ │ ├── ic_save_24dp.xml │ │ │ ├── ic_scan_24dp.xml │ │ │ ├── ic_select_all_24dp.xml │ │ │ ├── ic_settings_24dp.xml │ │ │ ├── ic_share_24dp.xml │ │ │ ├── ic_source_code_24dp.xml │ │ │ ├── ic_stop_24dp.xml │ │ │ ├── ic_subscriptions_24dp.xml │ │ │ ├── ic_telegram_24dp.xml │ │ │ └── nav_header_bg.png │ │ │ ├── drawable-xhdpi │ │ │ ├── ic_stat_direct.png │ │ │ ├── ic_stat_name.png │ │ │ ├── ic_stat_name_black.png │ │ │ └── ic_stat_proxy.png │ │ │ ├── drawable-xxhdpi │ │ │ ├── ic_stat_direct.png │ │ │ ├── ic_stat_name.png │ │ │ ├── ic_stat_name_black.png │ │ │ └── ic_stat_proxy.png │ │ │ ├── drawable-xxxhdpi │ │ │ ├── ic_stat_direct.png │ │ │ ├── ic_stat_name.png │ │ │ ├── ic_stat_name_black.png │ │ │ └── ic_stat_proxy.png │ │ │ ├── drawable │ │ │ ├── custom_divider.xml │ │ │ ├── ic_about_24dp.xml │ │ │ ├── ic_action_done.xml │ │ │ ├── ic_add_24dp.xml │ │ │ ├── ic_backup_24dp.xml │ │ │ ├── ic_check_update_24dp.xml │ │ │ ├── ic_circle.xml │ │ │ ├── ic_cloud_download_24dp.xml │ │ │ ├── ic_copy.xml │ │ │ ├── ic_delete_24dp.xml │ │ │ ├── ic_description_24dp.xml │ │ │ ├── ic_edit_24dp.xml │ │ │ ├── ic_fab_check.xml │ │ │ ├── ic_feedback_24dp.xml │ │ │ ├── ic_file_24dp.xml │ │ │ ├── ic_image_24dp.xml │ │ │ ├── ic_lock_24dp.xml │ │ │ ├── ic_logcat_24dp.xml │ │ │ ├── ic_more_vert_24dp.xml │ │ │ ├── ic_outline_filter_alt_24.xml │ │ │ ├── ic_per_apps_24dp.xml │ │ │ ├── ic_play_24dp.xml │ │ │ ├── ic_privacy_24dp.xml │ │ │ ├── ic_promotion_24dp.xml │ │ │ ├── ic_qu_scan_24dp.xml │ │ │ ├── ic_qu_switch_24dp.xml │ │ │ ├── ic_restore_24dp.xml │ │ │ ├── ic_rounded_corner_active.xml │ │ │ ├── ic_rounded_corner_inactive.xml │ │ │ ├── ic_routing_24dp.xml │ │ │ ├── ic_save_24dp.xml │ │ │ ├── ic_scan_24dp.xml │ │ │ ├── ic_select_all_24dp.xml │ │ │ ├── ic_settings_24dp.xml │ │ │ ├── ic_share_24dp.xml │ │ │ ├── ic_source_code_24dp.xml │ │ │ ├── ic_stop_24dp.xml │ │ │ ├── ic_subscriptions_24dp.xml │ │ │ ├── ic_telegram_24dp.xml │ │ │ ├── license_24px.xml │ │ │ └── nav_header_bg.png │ │ │ ├── font │ │ │ └── montserrat_thin.ttf │ │ │ ├── layout │ │ │ ├── activity_about.xml │ │ │ ├── activity_bypass_list.xml │ │ │ ├── activity_check_update.xml │ │ │ ├── activity_logcat.xml │ │ │ ├── activity_main.xml │ │ │ ├── activity_none.xml │ │ │ ├── activity_routing_edit.xml │ │ │ ├── activity_routing_setting.xml │ │ │ ├── activity_server_custom_config.xml │ │ │ ├── activity_server_hysteria2.xml │ │ │ ├── activity_server_shadowsocks.xml │ │ │ ├── activity_server_socks.xml │ │ │ ├── activity_server_trojan.xml │ │ │ ├── activity_server_vless.xml │ │ │ ├── activity_server_vmess.xml │ │ │ ├── activity_server_wireguard.xml │ │ │ ├── activity_settings.xml │ │ │ ├── activity_sub_edit.xml │ │ │ ├── activity_sub_setting.xml │ │ │ ├── activity_tasker.xml │ │ │ ├── activity_user_asset.xml │ │ │ ├── activity_user_asset_url.xml │ │ │ ├── dialog_config_filter.xml │ │ │ ├── item_qrcode.xml │ │ │ ├── item_recycler_bypass_list.xml │ │ │ ├── item_recycler_footer.xml │ │ │ ├── item_recycler_logcat.xml │ │ │ ├── item_recycler_main.xml │ │ │ ├── item_recycler_routing_setting.xml │ │ │ ├── item_recycler_sub_setting.xml │ │ │ ├── item_recycler_user_asset.xml │ │ │ ├── layout_address_port.xml │ │ │ ├── layout_tls.xml │ │ │ ├── layout_tls_hysteria2.xml │ │ │ ├── layout_transport.xml │ │ │ ├── nav_header.xml │ │ │ ├── preference_with_help_link.xml │ │ │ └── widget_switch.xml │ │ │ ├── menu │ │ │ ├── action_server.xml │ │ │ ├── action_sub_setting.xml │ │ │ ├── menu_asset.xml │ │ │ ├── menu_bypass_list.xml │ │ │ ├── menu_drawer.xml │ │ │ ├── menu_logcat.xml │ │ │ ├── menu_main.xml │ │ │ ├── menu_routing_setting.xml │ │ │ └── menu_scanner.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_banner.xml │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_foreground.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_banner.png │ │ │ ├── ic_banner_foreground.png │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── raw │ │ │ └── licenses.xml │ │ │ ├── values-ar │ │ │ └── strings.xml │ │ │ ├── values-bn │ │ │ └── strings.xml │ │ │ ├── values-bqi-rIR │ │ │ └── strings.xml │ │ │ ├── values-fa │ │ │ └── strings.xml │ │ │ ├── values-night │ │ │ ├── colors.xml │ │ │ └── themes.xml │ │ │ ├── values-ru │ │ │ └── strings.xml │ │ │ ├── values-sw360dp-v13 │ │ │ └── values-preference.xml │ │ │ ├── values-vi │ │ │ └── strings.xml │ │ │ ├── values-zh-rCN │ │ │ └── strings.xml │ │ │ ├── values-zh-rTW │ │ │ └── strings.xml │ │ │ ├── values │ │ │ ├── arrays.xml │ │ │ ├── attrs.xml │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── ic_banner_background.xml │ │ │ ├── ic_launcher_background.xml │ │ │ ├── strings.xml │ │ │ └── themes.xml │ │ │ └── xml │ │ │ ├── app_widget_provider.xml │ │ │ ├── cache_paths.xml │ │ │ ├── network_security_config.xml │ │ │ ├── pref_settings.xml │ │ │ └── shortcuts.xml │ │ ├── pre_release │ │ └── res │ │ │ └── values │ │ │ └── strings.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── v2ray │ │ └── ang │ │ ├── HttpUtilTest.kt │ │ └── UtilsTest.kt ├── build.gradle.kts ├── gradle.properties ├── gradle │ ├── libs.versions.toml │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle.kts ├── compile-tun2socks.sh ├── fastlane └── metadata │ └── android │ └── en-US │ ├── full_description.txt │ ├── images │ └── icon.png │ ├── short_description.txt │ └── title.txt ├── libhysteria2.sh └── tun2socks.mk /.github/ISSUE_TEMPLATE/bug_cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: v2rayNG程序问题 3 | about: 创建一个报告来帮助我们改进 4 | --- 5 | 6 | 在提出问题前请先自行排除服务器端问题,同时也请通过搜索确认是否有人提出过相同问题。 7 | 8 | 9 | ### 预期行为 10 | 描述你认为应该发生什么 11 | 12 | ### 实际行为 13 | 描述实际发生了什么 14 | 15 | ### 复现方法 16 | 1. 17 | 2. 18 | 3. 19 | 20 | ### 日志信息 21 |
22 | 23 | 通过`adb logcat -s com.v2ray.ang GoLog V2rayConfigUtilGoLog Main`获取日志。请自行删减日志中可能出现的敏感信息。 24 | 25 | 如果问题可重现,建议先执行`adb logcat -c`清空系统日志再执行上述命令,再操作重现问题。 26 | ``` 27 | 在这里粘贴日志 28 | ``` 29 |
30 | 31 | ### 环境信息 32 | 33 | ### 额外信息(可选) 34 | 35 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: V2Ray程序问题 4 | url: https://github.com/v2fly/v2ray-core/ 5 | about: 如果您有V2Ray而非v2rayNG的问题,请至这个链接讨论。 -------------------------------------------------------------------------------- /.github/workflows/fastlane.yml: -------------------------------------------------------------------------------- 1 | name: Validate Fastlane metadata 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: [ "master" ] 7 | pull_request: 8 | branches: [ "master" ] 9 | 10 | jobs: 11 | go: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | - name: Validate Fastlane Supply Metadata 16 | uses: ashutoshgngwr/validate-fastlane-supply-metadata@v2.1.0 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore data and key store files 2 | *.dat 3 | *.jks 4 | 5 | # Ignore output JSON file 6 | V2rayNG/app/release/output.json 7 | 8 | # Ignore IDE and build system directories 9 | .idea/ 10 | .gradle/ 11 | *.iml 12 | 13 | # Ignore local properties and DS_Store files 14 | /local.properties 15 | .DS_Store 16 | 17 | # Ignore build directories and captures 18 | /build 19 | /captures 20 | V2rayNG/app/build 21 | V2rayNG/build 22 | V2rayNG/local.properties 23 | 24 | # Ignore APK and AAR files 25 | *.apk 26 | *.aar 27 | 28 | # Ignore signing properties 29 | signing.properties 30 | 31 | # Ignore shared object files 32 | *.so 33 | 34 | # Ignore Google services JSON 35 | V2rayNG/app/google-services.json 36 | 37 | # Additional common Android/Java ignores 38 | *.log 39 | *.tmp 40 | *.bak 41 | *.swp 42 | *.orig 43 | *.class 44 | *.jar 45 | *.war 46 | *.ear 47 | 48 | # Ignore executable files 49 | *.exe 50 | *.dll 51 | *.obj 52 | *.o 53 | *.pyc 54 | *.pyo 55 | 56 | # Ignore files from other IDEs 57 | .vscode/ 58 | .classpath 59 | .project 60 | .settings/ 61 | *.sublime-workspace 62 | *.sublime-project 63 | 64 | # Ignore OS-specific files 65 | Thumbs.db 66 | .DS_Store 67 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "hysteria"] 2 | path = hysteria 3 | url = https://github.com/apernet/hysteria 4 | [submodule "AndroidLibXrayLite"] 5 | path = AndroidLibXrayLite 6 | url = https://github.com/2dust/AndroidLibXrayLite 7 | [submodule "badvpn"] 8 | path = badvpn 9 | url = https://github.com/XTLS/badvpn 10 | [submodule "libancillary"] 11 | path = libancillary 12 | url = https://github.com/shadowsocks/libancillary 13 | -------------------------------------------------------------------------------- /CR.md: -------------------------------------------------------------------------------- 1 | **v2rayNG 隐私权政策** 2 | 3 | 本政策自2023年11月17日起施行 4 | 5 | 2dust 将 v2rayNG 应用程序构建为开源应用程序。 本服务由 2dust 免费提供,并且旨在按原样使用。 6 | 7 | v2rayNG 尊重并保护所有用户的个人隐私权,为此我们向大众公开这份隐私权政策。**您使用 v2rayNG 即代表您以阅读并同意了这份条款,如果您不同意这份条款请立即停止使用并卸载 v2rayNG。** 8 | 9 | **信息收集** 10 | 11 | v2rayNG 软件自身不会发送任何信息到开发者,但是您下载软件的应用市场(如 Google Play)可能会收集关于应用运行状态的相关信息并提供给 v2rayNG 开发者。有关这些信息,请阅读您使用的应用市场所提供的隐私权政策。 12 | 13 | v2rayNG 软件中可能包含需要通过 IAP 支付解锁的功能,您的支付信息将由相关的 IAP 渠道进行处理,而我们对支付信息没有访问权。 14 | 15 | 当您向 v2rayNG 开发者反馈软件运行中的错误时,开发者可能会要求您提供软件以及系统的日志以帮助确认问题的原因。因日志中可能包括敏感信息,此类信息只能由您自己操作发送。**我们不对任何传输服务的安全性和隐私性做任何明示或暗示的担保,请您在传送相关信息时选择可以您自身可以接受的方式。** 16 | 17 | **信息共享** 18 | 19 | 我们不会向任何第三方出售收集到的用户数据。我们可能向外部开发者提供信息以协助软件的开发,但是在提供信息之前我们会传达相关保密义务并确定其可以遵守。 20 | 21 | **信息存留** 22 | 23 | 除非有相关法律规定,我们会在 30 天内清除不需要继续使用的用户数据,或将统计数据整合为无法识别单个用户的综合报告。 24 | 25 | **信息泄露** 26 | 27 | 我们会使用合理的技术和安全手段尽力保护用户的数据,但是无法保证数据的绝对安全。如果我们确认数据发生了泄露,我们会在 7 天内通过可用的渠道通知用户。**您同意不向我们追责任何因不可抗力而造成的损失。** 28 | 29 | **儿童隐私** 30 | 31 | 这些服务不针对 13 岁以下的任何人。我不会故意收集 13 岁以下儿童的个人身份信息。 如果我发现 13 岁以下的儿童向我提供了个人信息,我会立即从我们的服务器中删除该信息。 如果您是父母或监护人,并且您知道您的孩子向我们提供了个人信息,请与我联系,以便我能够采取必要的行动。 32 | 33 | **条款修改** 34 | 35 | 我们保留修改这份隐私权政策的权利,但是会确保在更新条款前至少 30 天通过我们的可用渠道和应用内提示来通知用户。**在新条款生效后继续使用软件即表示您同意修改后的隐私权政策。** 36 | 37 | **联系我们** 38 | 39 | 如果您对我的隐私政策有任何疑问或建议,请随时通过 CaptainIronng@protonmail.com 与我联系。 40 | 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # v2rayNG 2 | 3 | A V2Ray client for Android, support [Xray core](https://github.com/XTLS/Xray-core) and [v2fly core](https://github.com/v2fly/v2ray-core) 4 | 5 | [![API](https://img.shields.io/badge/API-21%2B-yellow.svg?style=flat)](https://developer.android.com/about/versions/lollipop) 6 | [![Kotlin Version](https://img.shields.io/badge/Kotlin-2.1.21-blue.svg)](https://kotlinlang.org) 7 | [![GitHub commit activity](https://img.shields.io/github/commit-activity/m/2dust/v2rayNG)](https://github.com/2dust/v2rayNG/commits/master) 8 | [![CodeFactor](https://www.codefactor.io/repository/github/2dust/v2rayng/badge)](https://www.codefactor.io/repository/github/2dust/v2rayng) 9 | [![GitHub Releases](https://img.shields.io/github/downloads/2dust/v2rayNG/latest/total?logo=github)](https://github.com/2dust/v2rayNG/releases) 10 | [![Chat on Telegram](https://img.shields.io/badge/Chat%20on-Telegram-brightgreen.svg)](https://t.me/v2rayn) 11 | 12 | ### Telegram Channel 13 | [github_2dust](https://t.me/github_2dust) 14 | 15 | ### Usage 16 | 17 | #### Geoip and Geosite 18 | - geoip.dat and geosite.dat files are in `Android/data/com.v2ray.ang/files/assets` (path may differ on some Android device) 19 | - download feature will get enhanced version in this [repo](https://github.com/Loyalsoldier/v2ray-rules-dat) (Note it need a working proxy) 20 | - latest official [domain list](https://github.com/Loyalsoldier/v2ray-rules-dat) and [ip list](https://github.com/Loyalsoldier/geoip) can be imported manually 21 | - 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) 22 | 23 | ### More in our [wiki](https://github.com/2dust/v2rayNG/wiki) 24 | 25 | ### Development guide 26 | 27 | Android project under V2rayNG folder can be compiled directly in Android Studio, or using Gradle wrapper. But the v2ray core inside the aar is (probably) outdated. 28 | The aar can be compiled from the Golang project [AndroidLibV2rayLite](https://github.com/2dust/AndroidLibV2rayLite) or [AndroidLibXrayLite](https://github.com/2dust/AndroidLibXrayLite). 29 | 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/) 30 | 31 | v2rayNG can run on Android Emulators. For WSA, VPN permission need to be granted via 32 | `appops set [package name] ACTIVATE_VPN allow` 33 | -------------------------------------------------------------------------------- /V2rayNG/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /V2rayNG/app/src/dev/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | v2rayNG (DEV) 4 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/assets/custom_routing_global: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "remarks": "阻断udp443", 4 | "outboundTag": "block", 5 | "port": "443", 6 | "network": "udp" 7 | }, 8 | { 9 | "remarks": "绕过局域网IP", 10 | "outboundTag": "direct", 11 | "ip": [ 12 | "geoip:private" 13 | ] 14 | }, 15 | { 16 | "remarks": "绕过局域网域名", 17 | "outboundTag": "direct", 18 | "domain": [ 19 | "geosite:private" 20 | ] 21 | }, 22 | { 23 | "remarks": "最终代理", 24 | "port": "0-65535", 25 | "outboundTag": "proxy" 26 | } 27 | ] -------------------------------------------------------------------------------- /V2rayNG/app/src/main/assets/custom_routing_white: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "remarks": "Google cn", 4 | "outboundTag": "proxy", 5 | "domain": [ 6 | "domain:googleapis.cn", 7 | "domain:gstatic.com" 8 | ] 9 | }, 10 | { 11 | "remarks": "阻断udp443", 12 | "outboundTag": "block", 13 | "port": "443", 14 | "network": "udp" 15 | }, 16 | { 17 | "remarks": "绕过局域网IP", 18 | "outboundTag": "direct", 19 | "ip": [ 20 | "geoip:private" 21 | ] 22 | }, 23 | { 24 | "remarks": "绕过局域网域名", 25 | "outboundTag": "direct", 26 | "domain": [ 27 | "geosite:private" 28 | ] 29 | }, 30 | { 31 | "remarks": "绕过中国公共DNSIP", 32 | "outboundTag": "direct", 33 | "ip": [ 34 | "223.5.5.5", 35 | "223.6.6.6", 36 | "2400:3200::1", 37 | "2400:3200:baba::1", 38 | "119.29.29.29", 39 | "1.12.12.12", 40 | "120.53.53.53", 41 | "2402:4e00::", 42 | "2402:4e00:1::", 43 | "180.76.76.76", 44 | "2400:da00::6666", 45 | "114.114.114.114", 46 | "114.114.115.115", 47 | "114.114.114.119", 48 | "114.114.115.119", 49 | "114.114.114.110", 50 | "114.114.115.110", 51 | "180.184.1.1", 52 | "180.184.2.2", 53 | "101.226.4.6", 54 | "218.30.118.6", 55 | "123.125.81.6", 56 | "140.207.198.6", 57 | "1.2.4.8", 58 | "210.2.4.8", 59 | "52.80.66.66", 60 | "117.50.22.22", 61 | "2400:7fc0:849e:200::4", 62 | "2404:c2c0:85d8:901::4", 63 | "117.50.10.10", 64 | "52.80.52.52", 65 | "2400:7fc0:849e:200::8", 66 | "2404:c2c0:85d8:901::8", 67 | "117.50.60.30", 68 | "52.80.60.30" 69 | ] 70 | }, 71 | { 72 | "remarks": "绕过中国公共DNS域名", 73 | "outboundTag": "direct", 74 | "domain": [ 75 | "domain:alidns.com", 76 | "domain:doh.pub", 77 | "domain:dot.pub", 78 | "domain:360.cn", 79 | "domain:onedns.net" 80 | ] 81 | }, 82 | { 83 | "remarks": "绕过中国IP", 84 | "outboundTag": "direct", 85 | "ip": [ 86 | "geoip:cn" 87 | ] 88 | }, 89 | { 90 | "remarks": "绕过中国域名", 91 | "outboundTag": "direct", 92 | "domain": [ 93 | "geosite:cn" 94 | ] 95 | } 96 | ] -------------------------------------------------------------------------------- /V2rayNG/app/src/main/assets/custom_routing_white_iran: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "remarks": "Block udp443", 4 | "outboundTag": "block", 5 | "port": "443", 6 | "network": "udp" 7 | }, 8 | { 9 | "remarks": "Direct LAN IP", 10 | "outboundTag": "direct", 11 | "ip": [ 12 | "geoip:private" 13 | ] 14 | }, 15 | { 16 | "remarks": "Direct LAN domains", 17 | "outboundTag": "direct", 18 | "domain": [ 19 | "geosite:private" 20 | ] 21 | }, 22 | { 23 | "remarks": "Bypass Iran domains", 24 | "outboundTag": "direct", 25 | "domain": [ 26 | "domain:ir", 27 | "geosite:category-ir" 28 | ] 29 | }, 30 | { 31 | "remarks": "Bypass Iran IP", 32 | "outboundTag": "direct", 33 | "ip": [ 34 | "geoip:ir" 35 | ] 36 | } 37 | ] 38 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/assets/v2ray_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "stats":{}, 3 | "log": { 4 | "loglevel": "warning" 5 | }, 6 | "policy":{ 7 | "levels": { 8 | "8": { 9 | "handshake": 4, 10 | "connIdle": 300, 11 | "uplinkOnly": 1, 12 | "downlinkOnly": 1 13 | } 14 | }, 15 | "system": { 16 | "statsOutboundUplink": true, 17 | "statsOutboundDownlink": true 18 | } 19 | }, 20 | "inbounds": [{ 21 | "tag": "socks", 22 | "port": 10808, 23 | "protocol": "socks", 24 | "settings": { 25 | "auth": "noauth", 26 | "udp": true, 27 | "userLevel": 8 28 | }, 29 | "sniffing": { 30 | "enabled": true, 31 | "destOverride": [ 32 | "http", 33 | "tls" 34 | ] 35 | } 36 | }, 37 | { 38 | "tag": "http", 39 | "port": 10809, 40 | "protocol": "http", 41 | "settings": { 42 | "userLevel": 8 43 | } 44 | } 45 | ], 46 | "outbounds": [{ 47 | "tag": "proxy", 48 | "protocol": "vmess", 49 | "settings": { 50 | "vnext": [ 51 | { 52 | "address": "v2ray.cool", 53 | "port": 10086, 54 | "users": [ 55 | { 56 | "id": "a3482e88-686a-4a58-8126-99c9df64b7bf", 57 | "alterId": 0, 58 | "security": "auto", 59 | "level": 8 60 | } 61 | ] 62 | } 63 | ], 64 | "servers": [ 65 | { 66 | "address": "v2ray.cool", 67 | "method": "chacha20", 68 | "ota": false, 69 | "password": "123456", 70 | "port": 10086, 71 | "level": 8 72 | } 73 | ] 74 | }, 75 | "streamSettings": { 76 | "network": "tcp" 77 | }, 78 | "mux": { 79 | "enabled": false 80 | } 81 | }, 82 | { 83 | "protocol": "freedom", 84 | "settings": { 85 | "domainStrategy": "UseIP" 86 | }, 87 | "tag": "direct" 88 | }, 89 | { 90 | "protocol": "blackhole", 91 | "tag": "block", 92 | "settings": { 93 | "response": { 94 | "type": "http" 95 | } 96 | } 97 | } 98 | ], 99 | "routing": { 100 | "domainStrategy": "AsIs", 101 | "rules": [] 102 | }, 103 | "dns": { 104 | "hosts": {}, 105 | "servers": [] 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/AngApplication.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang 2 | 3 | import android.content.Context 4 | import androidx.multidex.MultiDexApplication 5 | import androidx.work.Configuration 6 | import androidx.work.WorkManager 7 | import com.tencent.mmkv.MMKV 8 | import com.v2ray.ang.AppConfig.ANG_PACKAGE 9 | import com.v2ray.ang.handler.SettingsManager 10 | 11 | class AngApplication : MultiDexApplication() { 12 | companion object { 13 | lateinit var application: AngApplication 14 | } 15 | 16 | /** 17 | * Attaches the base context to the application. 18 | * @param base The base context. 19 | */ 20 | override fun attachBaseContext(base: Context?) { 21 | super.attachBaseContext(base) 22 | application = this 23 | } 24 | 25 | private val workManagerConfiguration: Configuration = Configuration.Builder() 26 | .setDefaultProcessName("${ANG_PACKAGE}:bg") 27 | .build() 28 | 29 | /** 30 | * Initializes the application. 31 | */ 32 | override fun onCreate() { 33 | super.onCreate() 34 | 35 | MMKV.initialize(this) 36 | 37 | SettingsManager.setNightMode() 38 | // Initialize WorkManager with the custom configuration 39 | WorkManager.initialize(this, workManagerConfiguration) 40 | 41 | SettingsManager.initRoutingRulesets(this) 42 | 43 | es.dmoral.toasty.Toasty.Config.getInstance() 44 | .setGravity(android.view.Gravity.BOTTOM, 0, 200) 45 | .apply() 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/dto/AppInfo.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.dto 2 | 3 | import android.graphics.drawable.Drawable 4 | 5 | data class AppInfo( 6 | val appName: String, 7 | val packageName: String, 8 | val appIcon: Drawable, 9 | val isSystemApp: Boolean, 10 | var isSelected: Int 11 | ) -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/dto/AssetUrlItem.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.dto 2 | 3 | data class AssetUrlItem( 4 | var remarks: String = "", 5 | var url: String = "", 6 | val addedTime: Long = System.currentTimeMillis(), 7 | var lastUpdated: Long = -1, 8 | var locked: Boolean? = false, 9 | ) -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/dto/CheckUpdateResult.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.dto 2 | 3 | data class CheckUpdateResult( 4 | val hasUpdate: Boolean, 5 | val latestVersion: String? = null, 6 | val releaseNotes: String? = null, 7 | val downloadUrl: String? = null, 8 | val error: String? = null, 9 | val isPreRelease: Boolean = false 10 | ) -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/dto/ConfigResult.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.dto 2 | 3 | data class ConfigResult( 4 | var status: Boolean, 5 | var guid: String? = null, 6 | var content: String = "", 7 | var socksPort: Int? = null, 8 | ) 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/dto/EConfigType.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.dto 2 | 3 | import com.v2ray.ang.AppConfig 4 | 5 | 6 | enum class EConfigType(val value: Int, val protocolScheme: String) { 7 | VMESS(1, AppConfig.VMESS), 8 | CUSTOM(2, AppConfig.CUSTOM), 9 | SHADOWSOCKS(3, AppConfig.SHADOWSOCKS), 10 | SOCKS(4, AppConfig.SOCKS), 11 | VLESS(5, AppConfig.VLESS), 12 | TROJAN(6, AppConfig.TROJAN), 13 | WIREGUARD(7, AppConfig.WIREGUARD), 14 | 15 | // TUIC(8, AppConfig.TUIC), 16 | HYSTERIA2(9, AppConfig.HYSTERIA2), 17 | HTTP(10, AppConfig.HTTP); 18 | 19 | companion object { 20 | fun fromInt(value: Int) = entries.firstOrNull { it.value == value } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/dto/GitHubRelease.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.dto 2 | 3 | import com.google.gson.annotations.SerializedName 4 | 5 | data class GitHubRelease( 6 | @SerializedName("tag_name") 7 | val tagName: String, 8 | @SerializedName("body") 9 | val body: String, 10 | @SerializedName("assets") 11 | val assets: List, 12 | @SerializedName("prerelease") 13 | val prerelease: Boolean = false, 14 | @SerializedName("published_at") 15 | val publishedAt: String = "" 16 | ) { 17 | data class Asset( 18 | @SerializedName("name") 19 | val name: String, 20 | @SerializedName("browser_download_url") 21 | val browserDownloadUrl: String 22 | ) 23 | } -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/dto/Hysteria2Bean.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.dto 2 | 3 | data class Hysteria2Bean( 4 | val server: String?, 5 | val auth: String?, 6 | val lazy: Boolean? = true, 7 | val obfs: ObfsBean? = null, 8 | val socks5: Socks5Bean? = null, 9 | val http: Socks5Bean? = null, 10 | val tls: TlsBean? = null, 11 | val transport: TransportBean? = null, 12 | val bandwidth: BandwidthBean? = null, 13 | ) { 14 | data class ObfsBean( 15 | val type: String?, 16 | val salamander: SalamanderBean? 17 | ) { 18 | data class SalamanderBean( 19 | val password: String?, 20 | ) 21 | } 22 | 23 | data class Socks5Bean( 24 | val listen: String?, 25 | ) 26 | 27 | data class TlsBean( 28 | val sni: String?, 29 | val insecure: Boolean?, 30 | val pinSHA256: String?, 31 | ) 32 | 33 | data class TransportBean( 34 | val type: String?, 35 | val udp: TransportUdpBean? 36 | ) { 37 | data class TransportUdpBean( 38 | val hopInterval: String?, 39 | ) 40 | } 41 | 42 | data class BandwidthBean( 43 | val down: String?, 44 | val up: String?, 45 | ) 46 | } -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/dto/IPAPIInfo.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.dto 2 | 3 | data class IPAPIInfo( 4 | var ip: String? = null, 5 | var clientIp: String? = null, 6 | var ip_addr: String? = null, 7 | var query: String? = null, 8 | var country: String? = null, 9 | var country_name: String? = null, 10 | var country_code: String? = null, 11 | var countryCode: String? = null 12 | ) -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/dto/Language.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.dto 2 | 3 | enum class Language(val code: String) { 4 | AUTO("auto"), 5 | ENGLISH("en"), 6 | CHINA("zh-rCN"), 7 | TRADITIONAL_CHINESE("zh-rTW"), 8 | VIETNAMESE("vi"), 9 | RUSSIAN("ru"), 10 | PERSIAN("fa"), 11 | ARABIC("ar"), 12 | BANGLA("bn"), 13 | BAKHTIARI("bqi-rIR"); 14 | 15 | companion object { 16 | fun fromCode(code: String): Language { 17 | return entries.find { it.code == code } ?: AUTO 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/dto/NetworkType.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.dto 2 | 3 | enum class NetworkType(val type: String) { 4 | TCP("tcp"), 5 | KCP("kcp"), 6 | WS("ws"), 7 | HTTP_UPGRADE("httpupgrade"), 8 | XHTTP("xhttp"), 9 | HTTP("http"), 10 | H2("h2"), 11 | 12 | //QUIC("quic"), 13 | GRPC("grpc"); 14 | 15 | companion object { 16 | fun fromString(type: String?) = entries.find { it.type == type } ?: TCP 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/dto/RoutingType.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.dto 2 | 3 | enum class RoutingType(val fileName: String) { 4 | WHITE("custom_routing_white"), 5 | BLACK("custom_routing_black"), 6 | GLOBAL("custom_routing_global"), 7 | WHITE_IRAN("custom_routing_white_iran"); 8 | 9 | companion object { 10 | fun fromIndex(index: Int): RoutingType { 11 | return when (index) { 12 | 0 -> WHITE 13 | 1 -> BLACK 14 | 2 -> GLOBAL 15 | 3 -> WHITE_IRAN 16 | else -> WHITE 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/dto/RulesetItem.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.dto 2 | 3 | data class RulesetItem( 4 | var remarks: String? = "", 5 | var ip: List? = null, 6 | var domain: List? = null, 7 | var outboundTag: String = "", 8 | var port: String? = null, 9 | var network: String? = null, 10 | var protocol: List? = null, 11 | var enabled: Boolean = true, 12 | var locked: Boolean? = false, 13 | ) -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/dto/ServerAffiliationInfo.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.dto 2 | 3 | data class ServerAffiliationInfo(var testDelayMillis: Long = 0L) { 4 | fun getTestDelayString(): String { 5 | if (testDelayMillis == 0L) { 6 | return "" 7 | } 8 | return testDelayMillis.toString() + "ms" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/dto/ServersCache.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.dto 2 | 3 | data class ServersCache( 4 | val guid: String, 5 | val profile: ProfileItem 6 | ) -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/dto/SubscriptionItem.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.dto 2 | 3 | data class SubscriptionItem( 4 | var remarks: String = "", 5 | var url: String = "", 6 | var enabled: Boolean = true, 7 | val addedTime: Long = System.currentTimeMillis(), 8 | var lastUpdated: Long = -1, 9 | var autoUpdate: Boolean = false, 10 | val updateInterval: Int? = null, 11 | var prevProfile: String? = null, 12 | var nextProfile: String? = null, 13 | var filter: String? = null, 14 | var allowInsecureUrl: Boolean = false, 15 | ) 16 | 17 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/dto/VmessQRCode.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.dto 2 | 3 | data class VmessQRCode( 4 | var v: String = "", 5 | var ps: String = "", 6 | var add: String = "", 7 | var port: String = "", 8 | var id: String = "", 9 | var aid: String = "0", 10 | var scy: String = "", 11 | var net: String = "", 12 | var type: String = "", 13 | var host: String = "", 14 | var path: String = "", 15 | var tls: String = "", 16 | var sni: String = "", 17 | var alpn: String = "", 18 | var fp: String = "" 19 | ) -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/fmt/CustomFmt.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.fmt 2 | 3 | import com.v2ray.ang.dto.EConfigType 4 | import com.v2ray.ang.dto.ProfileItem 5 | import com.v2ray.ang.dto.V2rayConfig 6 | import com.v2ray.ang.util.JsonUtil 7 | 8 | object CustomFmt : FmtBase() { 9 | /** 10 | * Parses a JSON string into a ProfileItem object. 11 | * 12 | * @param str the JSON string to parse 13 | * @return the parsed ProfileItem object, or null if parsing fails 14 | */ 15 | fun parse(str: String): ProfileItem? { 16 | val config = ProfileItem.create(EConfigType.CUSTOM) 17 | 18 | val fullConfig = JsonUtil.fromJson(str, V2rayConfig::class.java) 19 | val outbound = fullConfig.getProxyOutbound() 20 | 21 | config.remarks = fullConfig?.remarks ?: System.currentTimeMillis().toString() 22 | config.server = outbound?.getServerAddress() 23 | config.serverPort = outbound?.getServerPort().toString() 24 | 25 | return config 26 | } 27 | } -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/fmt/HttpFmt.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.fmt 2 | 3 | import com.v2ray.ang.dto.EConfigType 4 | import com.v2ray.ang.dto.ProfileItem 5 | import com.v2ray.ang.dto.V2rayConfig.OutboundBean 6 | import com.v2ray.ang.extension.isNotNullEmpty 7 | import com.v2ray.ang.handler.V2rayConfigManager 8 | 9 | object HttpFmt : FmtBase() { 10 | /** 11 | * Converts a ProfileItem object to an OutboundBean object. 12 | * 13 | * @param profileItem the ProfileItem object to convert 14 | * @return the converted OutboundBean object, or null if conversion fails 15 | */ 16 | fun toOutbound(profileItem: ProfileItem): OutboundBean? { 17 | val outboundBean = V2rayConfigManager.createInitOutbound(EConfigType.HTTP) 18 | 19 | outboundBean?.settings?.servers?.first()?.let { server -> 20 | server.address = getServerAddress(profileItem) 21 | server.port = profileItem.serverPort.orEmpty().toInt() 22 | if (profileItem.username.isNotNullEmpty()) { 23 | val socksUsersBean = OutboundBean.OutSettingsBean.ServersBean.SocksUsersBean() 24 | socksUsersBean.user = profileItem.username.orEmpty() 25 | socksUsersBean.pass = profileItem.password.orEmpty() 26 | server.users = listOf(socksUsersBean) 27 | } 28 | } 29 | 30 | return outboundBean 31 | } 32 | } -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/fmt/SocksFmt.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.fmt 2 | 3 | import com.v2ray.ang.dto.EConfigType 4 | import com.v2ray.ang.dto.ProfileItem 5 | import com.v2ray.ang.dto.V2rayConfig.OutboundBean 6 | import com.v2ray.ang.extension.idnHost 7 | import com.v2ray.ang.extension.isNotNullEmpty 8 | import com.v2ray.ang.handler.V2rayConfigManager 9 | import com.v2ray.ang.util.Utils 10 | import java.net.URI 11 | 12 | object SocksFmt : FmtBase() { 13 | /** 14 | * Parses a Socks URI string into a ProfileItem object. 15 | * 16 | * @param str the Socks URI string to parse 17 | * @return the parsed ProfileItem object, or null if parsing fails 18 | */ 19 | fun parse(str: String): ProfileItem? { 20 | val config = ProfileItem.create(EConfigType.SOCKS) 21 | 22 | val uri = URI(Utils.fixIllegalUrl(str)) 23 | if (uri.idnHost.isEmpty()) return null 24 | if (uri.port <= 0) return null 25 | 26 | config.remarks = Utils.urlDecode(uri.fragment.orEmpty()).let { if (it.isEmpty()) "none" else it } 27 | config.server = uri.idnHost 28 | config.serverPort = uri.port.toString() 29 | 30 | if (uri.userInfo?.isEmpty() == false) { 31 | val result = Utils.decode(uri.userInfo).split(":", limit = 2) 32 | if (result.count() == 2) { 33 | config.username = result.first() 34 | config.password = result.last() 35 | } 36 | } 37 | 38 | return config 39 | } 40 | 41 | /** 42 | * Converts a ProfileItem object to a URI string. 43 | * 44 | * @param config the ProfileItem object to convert 45 | * @return the converted URI string 46 | */ 47 | fun toUri(config: ProfileItem): String { 48 | val pw = 49 | if (config.username.isNotNullEmpty()) 50 | "${config.username}:${config.password}" 51 | else 52 | ":" 53 | 54 | return toUri(config, Utils.encode(pw), null) 55 | } 56 | 57 | /** 58 | * Converts a ProfileItem object to an OutboundBean object. 59 | * 60 | * @param profileItem the ProfileItem object to convert 61 | * @return the converted OutboundBean object, or null if conversion fails 62 | */ 63 | fun toOutbound(profileItem: ProfileItem): OutboundBean? { 64 | val outboundBean = V2rayConfigManager.createInitOutbound(EConfigType.SOCKS) 65 | 66 | outboundBean?.settings?.servers?.first()?.let { server -> 67 | server.address = getServerAddress(profileItem) 68 | server.port = profileItem.serverPort.orEmpty().toInt() 69 | if (profileItem.username.isNotNullEmpty()) { 70 | val socksUsersBean = OutboundBean.OutSettingsBean.ServersBean.SocksUsersBean() 71 | socksUsersBean.user = profileItem.username.orEmpty() 72 | socksUsersBean.pass = profileItem.password.orEmpty() 73 | server.users = listOf(socksUsersBean) 74 | } 75 | } 76 | 77 | return outboundBean 78 | } 79 | } -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/helper/CustomDividerItemDecoration.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.helper 2 | 3 | import android.graphics.Canvas 4 | import android.graphics.Rect 5 | import android.graphics.drawable.Drawable 6 | import android.view.View 7 | import androidx.recyclerview.widget.RecyclerView 8 | 9 | class CustomDividerItemDecoration( 10 | private val divider: Drawable, 11 | private val orientation: Int 12 | ) : RecyclerView.ItemDecoration() { 13 | 14 | override fun onDraw(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) { 15 | if (orientation == RecyclerView.VERTICAL) { 16 | drawVerticalDividers(canvas, parent) 17 | } else { 18 | drawHorizontalDividers(canvas, parent) 19 | } 20 | } 21 | 22 | private fun drawVerticalDividers(canvas: Canvas, parent: RecyclerView) { 23 | val left = parent.paddingLeft 24 | val right = parent.width - parent.paddingRight 25 | 26 | val childCount = parent.childCount 27 | for (i in 0 until childCount - 1) { 28 | val child = parent.getChildAt(i) 29 | val params = child.layoutParams as RecyclerView.LayoutParams 30 | 31 | val top = child.bottom + params.bottomMargin 32 | val bottom = top + divider.intrinsicHeight 33 | 34 | divider.setBounds(left, top, right, bottom) 35 | divider.draw(canvas) 36 | } 37 | } 38 | 39 | private fun drawHorizontalDividers(canvas: Canvas, parent: RecyclerView) { 40 | val top = parent.paddingTop 41 | val bottom = parent.height - parent.paddingBottom 42 | 43 | val childCount = parent.childCount 44 | for (i in 0 until childCount - 1) { 45 | val child = parent.getChildAt(i) 46 | val params = child.layoutParams as RecyclerView.LayoutParams 47 | 48 | val left = child.right + params.rightMargin 49 | val right = left + divider.intrinsicWidth 50 | 51 | divider.setBounds(left, top, right, bottom) 52 | divider.draw(canvas) 53 | } 54 | } 55 | 56 | override fun getItemOffsets( 57 | outRect: Rect, 58 | view: View, 59 | parent: RecyclerView, 60 | state: RecyclerView.State 61 | ) { 62 | if (orientation == RecyclerView.VERTICAL) { 63 | outRect.set(0, 0, 0, divider.intrinsicHeight) 64 | } else { 65 | outRect.set(0, 0, divider.intrinsicWidth, 0) 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/helper/ItemTouchHelperAdapter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Paul Burke 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.v2ray.ang.helper 17 | 18 | /** 19 | * Interface to listen for a move or dismissal event from a [ItemTouchHelper.Callback]. 20 | * 21 | * @author Paul Burke (ipaulpro) 22 | */ 23 | interface ItemTouchHelperAdapter { 24 | /** 25 | * Called when an item has been dragged far enough to trigger a move. This is called every time 26 | * an item is shifted, and **not** at the end of a "drop" event.

27 | *

28 | * Implementations should call [RecyclerView.Adapter.notifyItemMoved] after 29 | * adjusting the underlying data to reflect this move. 30 | * 31 | * @param fromPosition The start position of the moved item. 32 | * @param toPosition Then resolved position of the moved item. 33 | * @return True if the item was moved to the new adapter position. 34 | * @see RecyclerView.getAdapterPositionFor 35 | * @see RecyclerView.ViewHolder.getAdapterPosition 36 | */ 37 | fun onItemMove(fromPosition: Int, toPosition: Int): Boolean 38 | 39 | 40 | fun onItemMoveCompleted() 41 | 42 | /** 43 | * Called when an item has been dismissed by a swipe.

44 | *

45 | * Implementations should call [RecyclerView.Adapter.notifyItemRemoved] after 46 | * adjusting the underlying data to reflect this removal. 47 | * 48 | * @param position The position of the item dismissed. 49 | * @see RecyclerView.getAdapterPositionFor 50 | * @see RecyclerView.ViewHolder.getAdapterPosition 51 | */ 52 | fun onItemDismiss(position: Int) 53 | } 54 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/helper/ItemTouchHelperViewHolder.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Paul Burke 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.v2ray.ang.helper 17 | 18 | import androidx.recyclerview.widget.ItemTouchHelper 19 | 20 | /** 21 | * Interface to notify an item ViewHolder of relevant callbacks from [ ]. 22 | * 23 | * @author Paul Burke (ipaulpro) 24 | */ 25 | interface ItemTouchHelperViewHolder { 26 | /** 27 | * Called when the [ItemTouchHelper] first registers an item as being moved or swiped. 28 | * Implementations should update the item view to indicate it's active state. 29 | */ 30 | fun onItemSelected() 31 | 32 | 33 | /** 34 | * Called when the [ItemTouchHelper] has completed the move or swipe, and the active item 35 | * state should be cleared. 36 | */ 37 | fun onItemClear() 38 | } 39 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/plugin/NativePlugin.kt: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * * 3 | * Copyright (C) 2021 by nekohasekai * 4 | * Copyright (C) 2021 by Max Lv * 5 | * Copyright (C) 2021 by Mygod Studio * 6 | * * 7 | * This program is free software: you can redistribute it and/or modify * 8 | * it under the terms of the GNU General Public License as published by * 9 | * the Free Software Foundation, either version 3 of the License, or * 10 | * (at your option) any later version. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, * 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 15 | * GNU General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | ******************************************************************************/ 21 | 22 | package com.v2ray.ang.plugin 23 | 24 | import android.content.pm.ResolveInfo 25 | 26 | class NativePlugin(resolveInfo: ResolveInfo) : ResolvedPlugin(resolveInfo) { 27 | init { 28 | check(resolveInfo.providerInfo != null) 29 | } 30 | 31 | override val componentInfo get() = resolveInfo.providerInfo!! 32 | } 33 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/plugin/Plugin.kt: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * * 3 | * Copyright (C) 2021 by nekohasekai * 4 | * Copyright (C) 2021 by Max Lv * 5 | * Copyright (C) 2021 by Mygod Studio * 6 | * * 7 | * This program is free software: you can redistribute it and/or modify * 8 | * it under the terms of the GNU General Public License as published by * 9 | * the Free Software Foundation, either version 3 of the License, or * 10 | * (at your option) any later version. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, * 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 15 | * GNU General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program. If not, see . * 19 | * * 20 | ******************************************************************************/ 21 | 22 | package com.v2ray.ang.plugin 23 | 24 | import android.graphics.drawable.Drawable 25 | 26 | abstract class Plugin { 27 | abstract val id: String 28 | abstract val label: CharSequence 29 | abstract val version: Int 30 | abstract val versionName: String 31 | open val icon: Drawable? get() = null 32 | open val defaultConfig: String? get() = null 33 | open val packageName: String get() = "" 34 | open val directBootAware: Boolean get() = true 35 | 36 | override fun equals(other: Any?): Boolean { 37 | if (this === other) return true 38 | if (javaClass != other?.javaClass) return false 39 | return id == (other as Plugin).id 40 | } 41 | 42 | override fun hashCode() = id.hashCode() 43 | } 44 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/plugin/PluginContract.kt: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * * 3 | * Copyright (C) 2021 by nekohasekai * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | * * 18 | ******************************************************************************/ 19 | 20 | package com.v2ray.ang.plugin 21 | 22 | object PluginContract { 23 | 24 | const val ACTION_NATIVE_PLUGIN = "io.nekohasekai.sagernet.plugin.ACTION_NATIVE_PLUGIN" 25 | const val EXTRA_ENTRY = "io.nekohasekai.sagernet.plugin.EXTRA_ENTRY" 26 | const val METADATA_KEY_ID = "io.nekohasekai.sagernet.plugin.id" 27 | const val METADATA_KEY_EXECUTABLE_PATH = "io.nekohasekai.sagernet.plugin.executable_path" 28 | const val METHOD_GET_EXECUTABLE = "sagernet:getExecutable" 29 | 30 | const val COLUMN_PATH = "path" 31 | const val COLUMN_MODE = "mode" 32 | const val SCHEME = "plugin" 33 | } 34 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/receiver/BootReceiver.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.receiver 2 | 3 | import android.content.BroadcastReceiver 4 | import android.content.Context 5 | import android.content.Intent 6 | import com.v2ray.ang.handler.MmkvManager 7 | import com.v2ray.ang.service.V2RayServiceManager 8 | 9 | class BootReceiver : BroadcastReceiver() { 10 | /** 11 | * This method is called when the BroadcastReceiver is receiving an Intent broadcast. 12 | * It checks if the context is not null and the action is ACTION_BOOT_COMPLETED. 13 | * If the conditions are met, it starts the V2Ray service. 14 | * 15 | * @param context The Context in which the receiver is running. 16 | * @param intent The Intent being received. 17 | */ 18 | override fun onReceive(context: Context?, intent: Intent?) { 19 | if (context == null || intent?.action != Intent.ACTION_BOOT_COMPLETED) return 20 | if (!MmkvManager.decodeStartOnBoot() || MmkvManager.getSelectServer().isNullOrEmpty()) return 21 | V2RayServiceManager.startVService(context) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/receiver/TaskerReceiver.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.receiver 2 | 3 | import android.content.BroadcastReceiver 4 | import android.content.Context 5 | import android.content.Intent 6 | import android.text.TextUtils 7 | import com.v2ray.ang.AppConfig 8 | import com.v2ray.ang.service.V2RayServiceManager 9 | 10 | class TaskerReceiver : BroadcastReceiver() { 11 | 12 | /** 13 | * This method is called when the BroadcastReceiver is receiving an Intent broadcast. 14 | * It retrieves the bundle from the intent and checks the switch and guid values. 15 | * Depending on the switch value, it starts or stops the V2Ray service. 16 | * 17 | * @param context The Context in which the receiver is running. 18 | * @param intent The Intent being received. 19 | */ 20 | override fun onReceive(context: Context, intent: Intent?) { 21 | try { 22 | val bundle = intent?.getBundleExtra(AppConfig.TASKER_EXTRA_BUNDLE) 23 | val switch = bundle?.getBoolean(AppConfig.TASKER_EXTRA_BUNDLE_SWITCH, false) 24 | val guid = bundle?.getString(AppConfig.TASKER_EXTRA_BUNDLE_GUID).orEmpty() 25 | 26 | if (switch == null || TextUtils.isEmpty(guid)) { 27 | return 28 | } else if (switch) { 29 | if (guid == AppConfig.TASKER_DEFAULT_GUID) { 30 | V2RayServiceManager.startVServiceFromToggle(context) 31 | } else { 32 | V2RayServiceManager.startVService(context, guid) 33 | } 34 | } else { 35 | V2RayServiceManager.stopVService(context) 36 | } 37 | } catch (e: Exception) { 38 | android.util.Log.e(AppConfig.TAG, "Error processing Tasker broadcast", e) 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/service/ProcessService.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.service 2 | 3 | import android.content.Context 4 | import android.util.Log 5 | import com.v2ray.ang.AppConfig 6 | import kotlinx.coroutines.CoroutineScope 7 | import kotlinx.coroutines.Dispatchers 8 | import kotlinx.coroutines.launch 9 | 10 | class ProcessService { 11 | private var process: Process? = null 12 | 13 | /** 14 | * Runs a process with the given command. 15 | * @param context The context. 16 | * @param cmd The command to run. 17 | */ 18 | fun runProcess(context: Context, cmd: MutableList) { 19 | Log.i(AppConfig.TAG, cmd.toString()) 20 | 21 | try { 22 | val proBuilder = ProcessBuilder(cmd) 23 | proBuilder.redirectErrorStream(true) 24 | process = proBuilder 25 | .directory(context.filesDir) 26 | .start() 27 | 28 | CoroutineScope(Dispatchers.IO).launch { 29 | Thread.sleep(50L) 30 | Log.i(AppConfig.TAG, "runProcess check") 31 | process?.waitFor() 32 | Log.i(AppConfig.TAG, "runProcess exited") 33 | } 34 | Log.i(AppConfig.TAG, process.toString()) 35 | 36 | } catch (e: Exception) { 37 | Log.e(AppConfig.TAG, e.toString(), e) 38 | } 39 | } 40 | 41 | /** 42 | * Stops the running process. 43 | */ 44 | fun stopProcess() { 45 | try { 46 | Log.i(AppConfig.TAG, "runProcess destroy") 47 | process?.destroy() 48 | } catch (e: Exception) { 49 | Log.e(AppConfig.TAG, "Failed to destroy process", e) 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/service/ServiceControl.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.service 2 | 3 | import android.app.Service 4 | 5 | interface ServiceControl { 6 | /** 7 | * Gets the service instance. 8 | * @return The service instance. 9 | */ 10 | fun getService(): Service 11 | 12 | /** 13 | * Starts the service. 14 | */ 15 | fun startService() 16 | 17 | /** 18 | * Stops the service. 19 | */ 20 | fun stopService() 21 | 22 | /** 23 | * Protects the VPN socket. 24 | * @param socket The socket to protect. 25 | * @return True if the socket is protected, false otherwise. 26 | */ 27 | fun vpnProtect(socket: Int): Boolean 28 | } 29 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/service/SubscriptionUpdater.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.service 2 | 3 | import android.annotation.SuppressLint 4 | import android.app.NotificationChannel 5 | import android.app.NotificationManager 6 | import android.content.Context 7 | import android.os.Build 8 | import android.util.Log 9 | import androidx.core.app.NotificationCompat 10 | import androidx.core.app.NotificationManagerCompat 11 | import androidx.work.CoroutineWorker 12 | import androidx.work.WorkerParameters 13 | import com.v2ray.ang.AppConfig 14 | import com.v2ray.ang.AppConfig.SUBSCRIPTION_UPDATE_CHANNEL 15 | import com.v2ray.ang.AppConfig.SUBSCRIPTION_UPDATE_CHANNEL_NAME 16 | import com.v2ray.ang.R 17 | import com.v2ray.ang.handler.AngConfigManager.updateConfigViaSub 18 | import com.v2ray.ang.handler.MmkvManager 19 | 20 | object SubscriptionUpdater { 21 | 22 | class UpdateTask(context: Context, params: WorkerParameters) : 23 | CoroutineWorker(context, params) { 24 | 25 | private val notificationManager = NotificationManagerCompat.from(applicationContext) 26 | private val notification = 27 | NotificationCompat.Builder(applicationContext, SUBSCRIPTION_UPDATE_CHANNEL) 28 | .setWhen(0) 29 | .setTicker("Update") 30 | .setContentTitle(context.getString(R.string.title_pref_auto_update_subscription)) 31 | .setSmallIcon(R.drawable.ic_stat_name) 32 | .setCategory(NotificationCompat.CATEGORY_SERVICE) 33 | .setPriority(NotificationCompat.PRIORITY_DEFAULT) 34 | 35 | /** 36 | * Performs the subscription update work. 37 | * @return The result of the work. 38 | */ 39 | @SuppressLint("MissingPermission") 40 | override suspend fun doWork(): Result { 41 | Log.i(AppConfig.TAG, "subscription automatic update starting") 42 | 43 | val subs = MmkvManager.decodeSubscriptions().filter { it.second.autoUpdate } 44 | 45 | for (sub in subs) { 46 | val subItem = sub.second 47 | 48 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 49 | notification.setChannelId(SUBSCRIPTION_UPDATE_CHANNEL) 50 | val channel = 51 | NotificationChannel( 52 | SUBSCRIPTION_UPDATE_CHANNEL, 53 | SUBSCRIPTION_UPDATE_CHANNEL_NAME, 54 | NotificationManager.IMPORTANCE_MIN 55 | ) 56 | notificationManager.createNotificationChannel(channel) 57 | } 58 | notificationManager.notify(3, notification.build()) 59 | Log.i(AppConfig.TAG, "subscription automatic update: ---${subItem.remarks}") 60 | updateConfigViaSub(Pair(sub.first, subItem)) 61 | notification.setContentText("Updating ${subItem.remarks}") 62 | } 63 | notificationManager.cancel(3) 64 | return Result.success() 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/service/V2RayProxyOnlyService.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.service 2 | 3 | import android.app.Service 4 | import android.content.Context 5 | import android.content.Intent 6 | import android.os.Build 7 | import android.os.IBinder 8 | import androidx.annotation.RequiresApi 9 | import com.v2ray.ang.handler.SettingsManager 10 | import com.v2ray.ang.util.MyContextWrapper 11 | import java.lang.ref.SoftReference 12 | 13 | class V2RayProxyOnlyService : Service(), ServiceControl { 14 | /** 15 | * Initializes the service. 16 | */ 17 | override fun onCreate() { 18 | super.onCreate() 19 | V2RayServiceManager.serviceControl = SoftReference(this) 20 | } 21 | 22 | /** 23 | * Handles the start command for the service. 24 | * @param intent The intent. 25 | * @param flags The flags. 26 | * @param startId The start ID. 27 | * @return The start mode. 28 | */ 29 | override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { 30 | V2RayServiceManager.startCoreLoop() 31 | return START_STICKY 32 | } 33 | 34 | /** 35 | * Destroys the service. 36 | */ 37 | override fun onDestroy() { 38 | super.onDestroy() 39 | V2RayServiceManager.stopCoreLoop() 40 | } 41 | 42 | /** 43 | * Gets the service instance. 44 | * @return The service instance. 45 | */ 46 | override fun getService(): Service { 47 | return this 48 | } 49 | 50 | /** 51 | * Starts the service. 52 | */ 53 | override fun startService() { 54 | // do nothing 55 | } 56 | 57 | /** 58 | * Stops the service. 59 | */ 60 | override fun stopService() { 61 | stopSelf() 62 | } 63 | 64 | /** 65 | * Protects the VPN socket. 66 | * @param socket The socket to protect. 67 | * @return True if the socket is protected, false otherwise. 68 | */ 69 | override fun vpnProtect(socket: Int): Boolean { 70 | return true 71 | } 72 | 73 | /** 74 | * Binds the service. 75 | * @param intent The intent. 76 | * @return The binder. 77 | */ 78 | override fun onBind(intent: Intent?): IBinder? { 79 | return null 80 | } 81 | 82 | /** 83 | * Attaches the base context to the service. 84 | * @param newBase The new base context. 85 | */ 86 | @RequiresApi(Build.VERSION_CODES.N) 87 | override fun attachBaseContext(newBase: Context?) { 88 | val context = newBase?.let { 89 | MyContextWrapper.wrap(newBase, SettingsManager.getLocale()) 90 | } 91 | super.attachBaseContext(context) 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/ui/BaseActivity.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.ui 2 | 3 | import android.content.Context 4 | import android.os.Build 5 | import android.os.Bundle 6 | import android.view.MenuItem 7 | import androidx.annotation.RequiresApi 8 | import androidx.appcompat.app.AppCompatActivity 9 | import androidx.core.content.ContextCompat 10 | import androidx.core.view.WindowCompat 11 | import androidx.recyclerview.widget.DividerItemDecoration 12 | import androidx.recyclerview.widget.RecyclerView 13 | import com.v2ray.ang.handler.SettingsManager 14 | import com.v2ray.ang.helper.CustomDividerItemDecoration 15 | import com.v2ray.ang.util.MyContextWrapper 16 | import com.v2ray.ang.util.Utils 17 | 18 | 19 | abstract class BaseActivity : AppCompatActivity() { 20 | override fun onCreate(savedInstanceState: Bundle?) { 21 | super.onCreate(savedInstanceState) 22 | supportActionBar?.setDisplayHomeAsUpEnabled(true) 23 | if (!Utils.getDarkModeStatus(this)) { 24 | WindowCompat.getInsetsController(window, window.decorView).apply { 25 | isAppearanceLightStatusBars = true 26 | } 27 | } 28 | } 29 | 30 | override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) { 31 | android.R.id.home -> { 32 | // Handles the home button press by delegating to the onBackPressedDispatcher. 33 | // This ensures consistent back navigation behavior. 34 | onBackPressedDispatcher.onBackPressed() 35 | true 36 | } 37 | 38 | else -> super.onOptionsItemSelected(item) 39 | } 40 | 41 | @RequiresApi(Build.VERSION_CODES.N) 42 | override fun attachBaseContext(newBase: Context?) { 43 | super.attachBaseContext(MyContextWrapper.wrap(newBase ?: return, SettingsManager.getLocale())) 44 | } 45 | 46 | /** 47 | * Adds a custom divider to a RecyclerView. 48 | * 49 | * @param recyclerView The target RecyclerView to which the divider will be added. 50 | * @param context The context used to access resources. 51 | * @param drawableResId The resource ID of the drawable to be used as the divider. 52 | * @param orientation The orientation of the divider (DividerItemDecoration.VERTICAL or DividerItemDecoration.HORIZONTAL). 53 | */ 54 | fun addCustomDividerToRecyclerView(recyclerView: RecyclerView, context: Context?, drawableResId: Int, orientation: Int = DividerItemDecoration.VERTICAL) { 55 | // Get the drawable from resources 56 | val drawable = ContextCompat.getDrawable(context!!, drawableResId) 57 | requireNotNull(drawable) { "Drawable resource not found" } 58 | 59 | // Create a DividerItemDecoration with the specified orientation 60 | val dividerItemDecoration = CustomDividerItemDecoration(drawable, orientation) 61 | 62 | // Add the divider to the RecyclerView 63 | recyclerView.addItemDecoration(dividerItemDecoration) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/ui/CheckUpdateActivity.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.ui 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AlertDialog 5 | import androidx.lifecycle.lifecycleScope 6 | import com.v2ray.ang.AppConfig 7 | import com.v2ray.ang.BuildConfig 8 | import com.v2ray.ang.R 9 | import com.v2ray.ang.databinding.ActivityCheckUpdateBinding 10 | import com.v2ray.ang.dto.CheckUpdateResult 11 | import com.v2ray.ang.extension.toast 12 | import com.v2ray.ang.extension.toastSuccess 13 | import com.v2ray.ang.handler.MmkvManager 14 | import com.v2ray.ang.handler.SpeedtestManager 15 | import com.v2ray.ang.handler.UpdateCheckerManager 16 | import com.v2ray.ang.util.Utils 17 | import kotlinx.coroutines.launch 18 | 19 | class CheckUpdateActivity : BaseActivity() { 20 | 21 | private val binding by lazy { ActivityCheckUpdateBinding.inflate(layoutInflater) } 22 | 23 | override fun onCreate(savedInstanceState: Bundle?) { 24 | super.onCreate(savedInstanceState) 25 | setContentView(binding.root) 26 | 27 | title = getString(R.string.update_check_for_update) 28 | 29 | binding.layoutCheckUpdate.setOnClickListener { 30 | checkForUpdates(binding.checkPreRelease.isChecked) 31 | } 32 | 33 | binding.checkPreRelease.setOnCheckedChangeListener { _, isChecked -> 34 | MmkvManager.encodeSettings(AppConfig.PREF_CHECK_UPDATE_PRE_RELEASE, isChecked) 35 | } 36 | binding.checkPreRelease.isChecked = MmkvManager.decodeSettingsBool(AppConfig.PREF_CHECK_UPDATE_PRE_RELEASE, false) 37 | 38 | "v${BuildConfig.VERSION_NAME} (${SpeedtestManager.getLibVersion()})".also { 39 | binding.tvVersion.text = it 40 | } 41 | 42 | checkForUpdates(binding.checkPreRelease.isChecked) 43 | } 44 | 45 | private fun checkForUpdates(includePreRelease: Boolean) { 46 | toast(R.string.update_checking_for_update) 47 | 48 | lifecycleScope.launch { 49 | val result = UpdateCheckerManager.checkForUpdate(includePreRelease) 50 | if (result.hasUpdate) { 51 | showUpdateDialog(result) 52 | } else { 53 | toastSuccess(R.string.update_already_latest_version) 54 | } 55 | } 56 | } 57 | 58 | private fun showUpdateDialog(result: CheckUpdateResult) { 59 | AlertDialog.Builder(this) 60 | .setTitle(getString(R.string.update_new_version_found, result.latestVersion)) 61 | .setMessage(result.releaseNotes) 62 | .setPositiveButton(R.string.update_now) { _, _ -> 63 | result.downloadUrl?.let { 64 | Utils.openUri(this, it) 65 | } 66 | } 67 | .setNegativeButton(android.R.string.cancel, null) 68 | .show() 69 | } 70 | } -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/ui/FragmentAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.ui 2 | 3 | import androidx.fragment.app.Fragment 4 | import androidx.fragment.app.FragmentActivity 5 | import androidx.viewpager2.adapter.FragmentStateAdapter 6 | 7 | class FragmentAdapter(fragmentActivity: FragmentActivity, private val mFragments: List) : 8 | FragmentStateAdapter(fragmentActivity) { 9 | 10 | override fun createFragment(position: Int): Fragment { 11 | return mFragments[position] 12 | } 13 | 14 | override fun getItemCount(): Int { 15 | return mFragments.size 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/ui/LogcatRecyclerAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.ui 2 | 3 | import android.util.Log 4 | import android.view.LayoutInflater 5 | import android.view.ViewGroup 6 | import androidx.recyclerview.widget.RecyclerView 7 | import com.v2ray.ang.AppConfig 8 | import com.v2ray.ang.databinding.ItemRecyclerLogcatBinding 9 | 10 | class LogcatRecyclerAdapter(val activity: LogcatActivity) : RecyclerView.Adapter() { 11 | private var mActivity: LogcatActivity = activity 12 | 13 | 14 | override fun getItemCount() = mActivity.logsets.size 15 | 16 | override fun onBindViewHolder(holder: MainViewHolder, position: Int) { 17 | try { 18 | val log = mActivity.logsets[position] 19 | if (log.isEmpty()) { 20 | holder.itemSubSettingBinding.logTag.text = "" 21 | holder.itemSubSettingBinding.logContent.text = "" 22 | } else { 23 | val content = log.split("):", limit = 2) 24 | holder.itemSubSettingBinding.logTag.text = content.first().split("(", limit = 2).first().trim() 25 | holder.itemSubSettingBinding.logContent.text = if (content.count() > 1) content.last().trim() else "" 26 | } 27 | } catch (e: Exception) { 28 | Log.e(AppConfig.TAG, "Error binding log view data", e) 29 | } 30 | } 31 | 32 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainViewHolder { 33 | return MainViewHolder( 34 | ItemRecyclerLogcatBinding.inflate( 35 | LayoutInflater.from(parent.context), 36 | parent, 37 | false 38 | ) 39 | ) 40 | } 41 | 42 | class MainViewHolder(val itemSubSettingBinding: ItemRecyclerLogcatBinding) : RecyclerView.ViewHolder(itemSubSettingBinding.root) 43 | 44 | } 45 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/ui/ScScannerActivity.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.ui 2 | 3 | import android.Manifest 4 | import android.content.Intent 5 | import android.os.Bundle 6 | import androidx.activity.result.contract.ActivityResultContracts 7 | import com.v2ray.ang.R 8 | import com.v2ray.ang.extension.toast 9 | import com.v2ray.ang.extension.toastError 10 | import com.v2ray.ang.extension.toastSuccess 11 | import com.v2ray.ang.handler.AngConfigManager 12 | 13 | class ScScannerActivity : BaseActivity() { 14 | 15 | private val requestCameraPermissionLauncher = registerForActivityResult( 16 | ActivityResultContracts.RequestPermission() 17 | ) { isGranted: Boolean -> 18 | if (isGranted) { 19 | scanQRCode.launch(Intent(this, ScannerActivity::class.java)) 20 | } else { 21 | toast(R.string.toast_permission_denied) 22 | finish() 23 | } 24 | } 25 | 26 | override fun onCreate(savedInstanceState: Bundle?) { 27 | super.onCreate(savedInstanceState) 28 | setContentView(R.layout.activity_none) 29 | importQRcode() 30 | } 31 | 32 | private fun importQRcode(): Boolean { 33 | requestCameraPermissionLauncher.launch(Manifest.permission.CAMERA) 34 | return true 35 | } 36 | 37 | private val scanQRCode = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { 38 | if (it.resultCode == RESULT_OK) { 39 | val scanResult = it.data?.getStringExtra("SCAN_RESULT").orEmpty() 40 | val (count, countSub) = AngConfigManager.importBatchConfig(scanResult, "", false) 41 | 42 | if (count + countSub > 0) { 43 | toastSuccess(R.string.toast_success) 44 | } else { 45 | toastError(R.string.toast_failure) 46 | } 47 | 48 | startActivity(Intent(this, MainActivity::class.java)) 49 | } 50 | finish() 51 | } 52 | } -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/ui/ScSwitchActivity.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.ui 2 | 3 | import android.os.Bundle 4 | import com.v2ray.ang.R 5 | import com.v2ray.ang.service.V2RayServiceManager 6 | 7 | class ScSwitchActivity : BaseActivity() { 8 | override fun onCreate(savedInstanceState: Bundle?) { 9 | super.onCreate(savedInstanceState) 10 | moveTaskToBack(true) 11 | 12 | setContentView(R.layout.activity_none) 13 | 14 | if (V2RayServiceManager.isRunning()) { 15 | V2RayServiceManager.stopVService(this) 16 | } else { 17 | V2RayServiceManager.startVServiceFromToggle(this) 18 | } 19 | finish() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/util/AppManagerUtil.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.util 2 | 3 | import android.content.Context 4 | import android.content.pm.ApplicationInfo 5 | import android.content.pm.PackageManager 6 | import com.v2ray.ang.dto.AppInfo 7 | import kotlinx.coroutines.Dispatchers 8 | import kotlinx.coroutines.withContext 9 | 10 | object AppManagerUtil { 11 | /** 12 | * Load the list of network applications. 13 | * 14 | * @param context The context to use. 15 | * @return A list of AppInfo objects representing the network applications. 16 | */ 17 | suspend fun loadNetworkAppList(context: Context): ArrayList = 18 | withContext(Dispatchers.IO) { 19 | val packageManager = context.packageManager 20 | val packages = packageManager.getInstalledPackages(PackageManager.GET_PERMISSIONS) 21 | val apps = ArrayList() 22 | 23 | for (pkg in packages) { 24 | val applicationInfo = pkg.applicationInfo ?: continue 25 | 26 | val appName = applicationInfo.loadLabel(packageManager).toString() 27 | val appIcon = applicationInfo.loadIcon(packageManager) ?: continue 28 | val isSystemApp = applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM > 0 29 | 30 | val appInfo = AppInfo(appName, pkg.packageName, appIcon, isSystemApp, 0) 31 | apps.add(appInfo) 32 | } 33 | 34 | return@withContext apps 35 | } 36 | 37 | fun getLastUpdateTime(context: Context): Long = 38 | context.packageManager.getPackageInfo(context.packageName, 0).lastUpdateTime 39 | 40 | } 41 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/util/JsonUtil.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.util 2 | 3 | import android.util.Log 4 | import com.google.gson.Gson 5 | import com.google.gson.GsonBuilder 6 | import com.google.gson.JsonObject 7 | import com.google.gson.JsonParser 8 | import com.google.gson.JsonPrimitive 9 | import com.google.gson.JsonSerializationContext 10 | import com.google.gson.JsonSerializer 11 | import com.google.gson.reflect.TypeToken 12 | import com.v2ray.ang.AppConfig 13 | import java.lang.reflect.Type 14 | 15 | object JsonUtil { 16 | private var gson = Gson() 17 | 18 | /** 19 | * Converts an object to its JSON representation. 20 | * 21 | * @param src The object to convert. 22 | * @return The JSON representation of the object. 23 | */ 24 | fun toJson(src: Any?): String { 25 | return gson.toJson(src) 26 | } 27 | 28 | /** 29 | * Parses a JSON string into an object of the specified class. 30 | * 31 | * @param src The JSON string to parse. 32 | * @param cls The class of the object to parse into. 33 | * @return The parsed object. 34 | */ 35 | fun fromJson(src: String, cls: Class): T { 36 | return gson.fromJson(src, cls) 37 | } 38 | 39 | /** 40 | * Converts an object to its pretty-printed JSON representation. 41 | * 42 | * @param src The object to convert. 43 | * @return The pretty-printed JSON representation of the object, or null if the object is null. 44 | */ 45 | fun toJsonPretty(src: Any?): String? { 46 | if (src == null) 47 | return null 48 | val gsonPre = GsonBuilder() 49 | .setPrettyPrinting() 50 | .disableHtmlEscaping() 51 | .registerTypeAdapter( // custom serializer is needed here since JSON by default parse number as Double, core will fail to start 52 | object : TypeToken() {}.type, 53 | JsonSerializer { src: Double?, _: Type?, _: JsonSerializationContext? -> 54 | JsonPrimitive( 55 | src?.toInt() 56 | ) 57 | } 58 | ) 59 | .create() 60 | return gsonPre.toJson(src) 61 | } 62 | 63 | /** 64 | * Parses a JSON string into a JsonObject. 65 | * 66 | * @param src The JSON string to parse. 67 | * @return The parsed JsonObject, or null if parsing fails. 68 | */ 69 | fun parseString(src: String?): JsonObject? { 70 | if (src == null) 71 | return null 72 | try { 73 | return JsonParser.parseString(src).getAsJsonObject() 74 | } catch (e: Exception) { 75 | Log.e(AppConfig.TAG, "Failed to parse JSON string", e) 76 | return null 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/util/MessageUtil.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.util 2 | 3 | import android.content.ComponentName 4 | import android.content.Context 5 | import android.content.Intent 6 | import android.util.Log 7 | import com.v2ray.ang.AppConfig 8 | import com.v2ray.ang.service.V2RayTestService 9 | import java.io.Serializable 10 | 11 | object MessageUtil { 12 | 13 | 14 | /** 15 | * Sends a message to the service. 16 | * 17 | * @param ctx The context. 18 | * @param what The message identifier. 19 | * @param content The message content. 20 | */ 21 | fun sendMsg2Service(ctx: Context, what: Int, content: Serializable) { 22 | sendMsg(ctx, AppConfig.BROADCAST_ACTION_SERVICE, what, content) 23 | } 24 | 25 | /** 26 | * Sends a message to the UI. 27 | * 28 | * @param ctx The context. 29 | * @param what The message identifier. 30 | * @param content The message content. 31 | */ 32 | fun sendMsg2UI(ctx: Context, what: Int, content: Serializable) { 33 | sendMsg(ctx, AppConfig.BROADCAST_ACTION_ACTIVITY, what, content) 34 | } 35 | 36 | /** 37 | * Sends a message to the test service. 38 | * 39 | * @param ctx The context. 40 | * @param what The message identifier. 41 | * @param content The message content. 42 | */ 43 | fun sendMsg2TestService(ctx: Context, what: Int, content: Serializable) { 44 | try { 45 | val intent = Intent() 46 | intent.component = ComponentName(ctx, V2RayTestService::class.java) 47 | intent.putExtra("key", what) 48 | intent.putExtra("content", content) 49 | ctx.startService(intent) 50 | } catch (e: Exception) { 51 | Log.e(AppConfig.TAG, "Failed to send message to test service", e) 52 | } 53 | } 54 | 55 | /** 56 | * Sends a message with the specified action. 57 | * 58 | * @param ctx The context. 59 | * @param action The action string. 60 | * @param what The message identifier. 61 | * @param content The message content. 62 | */ 63 | private fun sendMsg(ctx: Context, action: String, what: Int, content: Serializable) { 64 | try { 65 | val intent = Intent() 66 | intent.action = action 67 | intent.`package` = AppConfig.ANG_PACKAGE 68 | intent.putExtra("key", what) 69 | intent.putExtra("content", content) 70 | ctx.sendBroadcast(intent) 71 | } catch (e: Exception) { 72 | Log.e(AppConfig.TAG, "Failed to send message with action: $action", e) 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/java/com/v2ray/ang/util/MyContextWrapper.kt: -------------------------------------------------------------------------------- 1 | package com.v2ray.ang.util 2 | 3 | import android.content.Context 4 | import android.content.ContextWrapper 5 | import android.content.res.Configuration 6 | import android.content.res.Resources 7 | import android.os.Build 8 | import android.os.LocaleList 9 | import androidx.annotation.RequiresApi 10 | import java.util.Locale 11 | 12 | open class MyContextWrapper(base: Context?) : ContextWrapper(base) { 13 | companion object { 14 | /** 15 | * Wraps the context with a new locale. 16 | * 17 | * @param context The original context. 18 | * @param newLocale The new locale to set. 19 | * @return A ContextWrapper with the new locale. 20 | */ 21 | @RequiresApi(Build.VERSION_CODES.N) 22 | fun wrap(context: Context, newLocale: Locale?): ContextWrapper { 23 | var mContext = context 24 | val res: Resources = mContext.resources 25 | val configuration: Configuration = res.configuration 26 | mContext = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 27 | configuration.setLocale(newLocale) 28 | val localeList = LocaleList(newLocale) 29 | LocaleList.setDefault(localeList) 30 | configuration.setLocales(localeList) 31 | mContext.createConfigurationContext(configuration) 32 | } else { 33 | configuration.setLocale(newLocale) 34 | mContext.createConfigurationContext(configuration) 35 | } 36 | return ContextWrapper(mContext) 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/color/color_highlight_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-hdpi/ic_stat_direct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-hdpi/ic_stat_direct.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-hdpi/ic_stat_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-hdpi/ic_stat_name.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-hdpi/ic_stat_proxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-hdpi/ic_stat_proxy.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-mdpi/ic_stat_direct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-mdpi/ic_stat_direct.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-mdpi/ic_stat_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-mdpi/ic_stat_name.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-mdpi/ic_stat_name_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-mdpi/ic_stat_name_black.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-mdpi/ic_stat_proxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-mdpi/ic_stat_proxy.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_about_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_action_done.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_add_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_backup_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_check_update_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_cloud_download_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_copy.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_delete_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_description_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_edit_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_fab_check.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_feedback_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_file_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_image_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_lock_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_logcat_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_more_vert_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_outline_filter_alt_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_per_apps_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_play_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_privacy_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_promotion_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_restore_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_routing_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_save_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_scan_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_select_all_24dp.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_settings_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_share_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_source_code_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_stop_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_subscriptions_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/ic_telegram_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-night/nav_header_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-night/nav_header_bg.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-xhdpi/ic_stat_direct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-xhdpi/ic_stat_direct.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-xhdpi/ic_stat_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-xhdpi/ic_stat_name.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-xhdpi/ic_stat_name_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-xhdpi/ic_stat_name_black.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-xhdpi/ic_stat_proxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-xhdpi/ic_stat_proxy.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-xxhdpi/ic_stat_direct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-xxhdpi/ic_stat_direct.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-xxhdpi/ic_stat_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-xxhdpi/ic_stat_name.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-xxhdpi/ic_stat_name_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-xxhdpi/ic_stat_name_black.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-xxhdpi/ic_stat_proxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-xxhdpi/ic_stat_proxy.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-xxxhdpi/ic_stat_direct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-xxxhdpi/ic_stat_direct.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-xxxhdpi/ic_stat_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-xxxhdpi/ic_stat_name.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-xxxhdpi/ic_stat_name_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-xxxhdpi/ic_stat_name_black.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable-xxxhdpi/ic_stat_proxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable-xxxhdpi/ic_stat_proxy.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/custom_divider.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_about_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_action_done.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_add_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_backup_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_check_update_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_circle.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_cloud_download_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_copy.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_delete_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_description_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_edit_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_fab_check.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_feedback_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_file_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_image_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_lock_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_logcat_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_more_vert_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_outline_filter_alt_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_per_apps_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_play_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_privacy_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_promotion_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_qu_scan_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | 13 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_qu_switch_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_restore_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_rounded_corner_active.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_rounded_corner_inactive.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_routing_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_save_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_scan_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_select_all_24dp.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_settings_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_share_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_source_code_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_stop_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_subscriptions_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/ic_telegram_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/license_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/drawable/nav_header_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/drawable/nav_header_bg.png -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/font/montserrat_thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2dust/v2rayNG/9d1f98ff34c2e085389357c500e2ce22987cae9e/V2rayNG/app/src/main/res/font/montserrat_thin.ttf -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/layout/activity_logcat.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/layout/activity_none.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/layout/activity_server_shadowsocks.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 16 | 17 | 22 | 23 | 27 | 28 | 33 | 34 | 35 | 36 | 37 | 42 | 43 | 47 | 48 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/layout/activity_server_socks.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 16 | 17 | 22 | 23 | 27 | 28 | 29 | 34 | 35 | 36 | 37 | 42 | 43 | 47 | 48 | 53 | 54 | 55 | 56 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/layout/activity_server_trojan.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 16 | 17 | 22 | 23 | 27 | 28 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/layout/activity_server_vmess.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 16 | 17 | 22 | 23 | 27 | 28 | 33 | 34 | 35 | 36 | 41 | 42 | 46 | 47 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/layout/activity_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/layout/activity_sub_setting.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 17 | 18 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/layout/activity_tasker.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 15 | 16 | 24 | 25 | 33 | 34 | 35 | 36 | 41 | 42 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/layout/dialog_config_filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 12 | 17 | 18 | 24 | 25 | 26 | 27 | 32 | 33 | 37 | 38 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/layout/item_qrcode.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/layout/item_recycler_bypass_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 16 | 17 | 23 | 24 | 30 | 31 | 38 | 39 | 40 | 47 | 48 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/layout/item_recycler_footer.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 17 | 18 | 23 | 24 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/layout/item_recycler_logcat.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 16 | 17 | 22 | 23 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/layout/layout_address_port.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 17 | 18 | 19 | 24 | 25 | 29 | 30 | 35 | 36 | 37 | 38 | 43 | 44 | 48 | 49 | 54 | 55 | 56 | 57 | 62 | 63 | 67 | 68 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/layout/nav_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /V2rayNG/app/src/main/res/layout/preference_with_help_link.xml: -------------------------------------------------------------------------------- 1 | 2 |