更新记录

1.0.1(2026-06-07)

-增加支持 从微信 或者其他软件 打开.ovpn文件直接导入app

1.0.0(2026-06-07)

-Android 接入基于OpenV3


平台兼容性

uni-app(4.0)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× × 7.0 - -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × - × - - - -

其他

多语言 暗黑模式 宽屏模式
× ×

ly028-OpenV

OpenVPN3 UTS 插件 — 全平台 OpenVPN 客户端
基于 OpenVPN3 核心引擎,提供稳定的 VPN 隧道服务。

ly028-OpenV

📥 体验

QR Code 扫码下载 APK
📲 直接下载
Android minSdkVersion 24



重要说明:本插件是技术组件,不提供任何 VPN 节点、订阅或上网服务。集成方须自行准备 OpenVPN 服务器与配置,并独立承担合规责任。


📋 目录


📖 简介

ly028-OpenV 是基于 OpenVPN3 核心引擎的 uni-app UTS 插件,为 App 提供完整的 OpenVPN 客户端能力:

  • .ovpn 配置导入(文件选择 / 粘贴文本)
  • ✅ VPN 连接 / 断开 / 重连
  • ✅ 实时连接状态回调
  • ✅ 实时日志输出(支持级别过滤)
  • ✅ 实时流量统计与速度计算
  • ✅ 多配置管理(保存 / 编辑 / 删除)
  • ✅ 配置持久化存储
  • ✅ Android 前台服务通知栏(连接中 / 已连接 / 流量显示)
  • ✅ 多语言支持(中文 / English)
  • ✅ 国际化通知栏文案

📱 平台支持

平台 状态 备注
Android 已完成 minSdkVersion 24,API 14+
iOS 🔧 开发中 暂未实现
HarmonyOS 待规划 -

🔧 安装

方式一:插件市场安装

  1. 打开 HBuilderX → 插件市场 → 搜索 ly028-OpenV
  2. 点击「使用 HBuilderX 导入插件」
  3. manifest.jsonApp模块配置 中确认插件已勾选

方式二:手动安装

uni_modules/ly028-OpenV 目录复制到项目 uni_modules/ 下即可。


🚀 快速开始

// 1. 导入插件
import { initApp, connect, disconnect, onStatus } from '@/uni_modules/ly028-OpenV'
import type { OpenVpnConfig } from '@/uni_modules/ly028-OpenV'

// 2. 初始化
initApp()

// 3. 监听状态变化
onStatus((state) => {
    console.log('VPN 状态:', state)
    // state: 'DISCONNECTED' | 'CONNECTING' | 'CONNECTED' | 'ERROR' | ...
})

// 4. 发起连接
const config: OpenVpnConfig = {
    content: `
        client
        dev tun
        proto udp
        remote your-server.com 1194
        ...
    `,
    username: 'user',
    password: 'pass',
}
connect(config)

// 5. 断开连接
disconnect()

📚 API 文档

初始化

initApp(): void

初始化 OpenVPN 插件。必须在调用其他 API 之前调用。

建议在 App.vueonLaunch 中调用:

import { initApp } from '@/uni_modules/ly028-OpenV'

export default {
    onLaunch() {
        initApp()
    }
}

连接控制

connect(config: OpenVpnConfig): boolean

使用 OpenVpnConfig 对象发起 VPN 连接。

参数 类型 说明
config.content string 必需。.ovpn 配置文件完整内容
config.username string? 用户名(仅 userpass 认证)
config.password string? 密码(仅 userpass 认证)
config.serverOverride string? 服务器地址覆盖
config.portOverride string? 端口覆盖
config.protoOverride string? 协议覆盖(udp/tcp)

返回: boolean — 连接是否成功发起。

connectByProfile(profileId: number): boolean

通过已保存的配置 ID 连接(密码不经过前端)。

参数 类型 说明
profileId number 已保存配置的 ID

返回: boolean

disconnect(): boolean

断开当前 VPN 连接。

返回: boolean


配置管理

evalConfig(config: OpenVpnConfig): OpenVpnEvalResult

评估配置内容,解析服务器信息而不保存。

参数 类型 说明
config.content string .ovpn 配置内容

返回: OpenVpnEvalResult

const result = evalConfig({ content: sampleOvpn })
if (!result.error) {
    console.log('服务器:', result.remoteHost, ':', result.remotePort, result.remoteProto)
    console.log('认证方式:', result.autologin ? '证书' : '用户名/密码')
}

importConfigFromText(text: string): OpenVpnImportResult

导入配置文本并返回解析结果(不保存到配置列表)。

参数 类型 说明
text string .ovpn 配置文本

返回: OpenVpnImportResult

importAndSaveProfile(content: string): OpenVpnProfileDetail | null

导入配置文本并自动保存到配置列表。

参数 类型 说明
content string .ovpn 配置文本

返回: OpenVpnProfileDetailnull(导入失败)

pickAndImportFile(callback: (profileId: number) => void): void

打开系统文件选择器,选择 .ovpn / .conf 文件后自动导入。

参数 类型 说明
callback (profileId: number) => void 导入完成回调,profileId > 0 表示成功

getProfiles(): Array<OpenVpnProfileSummary>

获取所有已保存配置的概要列表。

返回: OpenVpnProfileSummary[]

getProfileDetail(id: number): OpenVpnProfileDetail | null

获取指定配置的完整详情。

参数 类型 说明
id number 配置 ID

返回: OpenVpnProfileDetailnull

saveOrUpdateProfile(...): number

统一保存/更新配置:id > 0 更新,id <= 0 新建。

参数 类型 说明
id number 配置 ID(<= 0 表示新建)
name string 配置名称
content string .ovpn 内容
serverHost string 服务器地址
serverPort string 端口
serverProto string 协议
autologin boolean 是否证书认证
username string 用户名
password string 密码

返回: number — 配置 ID

deleteProfile(id: number): void

删除指定配置。

参数 类型 说明
id number 配置 ID

getLastUsedProfileId(): number

获取上次使用的配置 ID。

返回: number(-1 表示无上次记录)

setLastUsedProfileId(id: number): void

记录上次使用的配置 ID。

参数 类型 说明
id number 配置 ID

状态与流量

getStatus(): OpenVpnStatus

获取当前 VPN 连接状态。

返回: OpenVpnStatus

const status = getStatus()
console.log('状态:', status.state)
console.log('服务器:', status.serverHost)
console.log('VPN IP:', status.vpnIp4)

getVersion(): string

获取插件版本号。

返回: string

getTrafficStats(): OpenVpnTrafficStats

获取流量统计数据。

返回: OpenVpnTrafficStats


事件监听

onStatus(callback: OpenVpnStatusCallback): void

注册连接状态变化监听器。

参数 类型 说明
callback (state: OpenVpnState) => void 状态回调

OpenVpnState 可选值:'DISCONNECTED' | 'CONNECTING' | 'CONNECTED' | 'PAUSED' | 'RECONNECTING' | 'STOPPING' | 'ERROR'

onLog(callback: OpenVpnLogCallback): void

注册日志输出监听器。

参数 类型 说明
callback (level: string, text: string) => void 日志回调,level 为 'info' / 'warn' / 'error' / 'debug'

onTraffic(callback: OpenVpnTrafficCallback): void

注册流量统计监听器(约每秒回调一次)。

参数 类型 说明
callback (stats: OpenVpnTrafficStats) => void 流量回调

getCachedLogs(): Array<OpenVpnLogEntry>

获取缓存的日志列表(上限 200 条)。适合日志页面初始化时加载历史日志。

返回: OpenVpnLogEntry[]

removeAllListeners(): void

移除所有已注册的事件监听器。建议在页面卸载时调用。


语言设置

setAppLanguage(language: string): void

设置原生层语言(影响通知栏文字)。

参数 类型 说明
language string 'zh-Hans''en'

前端语言切换使用 uni.setLocale(),详见 uni-app 国际化文档


设置持久化

getSetting(key: string, defaultVal: string): string

读取持久化设置项。

参数 类型 说明
key string 设置键名
defaultVal string 默认值

返回: string

setSetting(key: string, value: string): void

保存持久化设置项。

参数 类型 说明
key string 设置键名
value string 设置值

错误码

常量 说明
ERR_OK 0 成功
ERR_FAIL 1 通用错误
ERR_NOT_INIT 2 插件未初始化
ERR_PERMISSION 3 VPN 权限未授予
ERR_CONFIG 4 配置无效
ERR_CONNECT 5 连接失败
import { ERR_OK, ERR_CONFIG, getErrorMessage } from '@/uni_modules/ly028-OpenV'

const msg = getErrorMessage(ERR_CONFIG) // "Invalid configuration"

📦 类型定义

OpenVpnConfig

type OpenVpnConfig = {
    content: string           // .ovpn 配置完整内容
    name?: string             // 配置名称
    username?: string         // 用户名
    password?: string         // 密码
    serverOverride?: string   // 服务器地址覆盖
    portOverride?: string     // 端口覆盖
    protoOverride?: string    // 协议覆盖(udp/tcp)
}

OpenVpnState

type OpenVpnState = 'DISCONNECTED' | 'CONNECTING' | 'CONNECTED'
    | 'PAUSED' | 'RECONNECTING' | 'STOPPING' | 'ERROR'

OpenVpnStatus

type OpenVpnStatus = {
    state: OpenVpnState       // 连接状态
    serverHost?: string       // 服务器地址
    serverPort?: string       // 服务器端口
    serverProto?: string      // 协议
    vpnIp4?: string           // VPN 分配的 IPv4 地址
    vpnMtu?: number           // MTU 值
    uptime?: number           // 已连接时长(秒)
    error?: string            // 错误信息
}

OpenVpnTrafficStats

type OpenVpnTrafficStats = {
    bytesIn: number           // 总下行字节数
    bytesOut: number          // 总上行字节数
    speedIn?: number          // 当前下行速度(字节/秒)
    speedOut?: number         // 当前上行速度(字节/秒)
}

OpenVpnEvalResult

type OpenVpnEvalResult = {
    error: boolean            // 是否有错误
    message?: string          // 错误消息
    autologin: boolean        // 是否支持证书自动登录
    externalPki: boolean      // 是否使用外部 PKI
    remoteHost?: string       // 解析到的服务器地址
    remotePort?: string       // 解析到的服务器端口
    remoteProto?: string      // 解析到的协议
    profileName?: string      // 配置名称
    friendlyName?: string     // 友好名称
    serverList?: string       // 服务器列表
}

OpenVpnImportResult

type OpenVpnImportResult = {
    error: boolean
    message?: string
    autologin: boolean
    externalPki: boolean
    remoteHost?: string
    remotePort?: string
    remoteProto?: string
    profileName?: string
    friendlyName?: string
    content?: string
}

OpenVpnProfileSummary

type OpenVpnProfileSummary = {
    id: number                // 配置 ID
    name: string              // 配置名称
    serverHost: string        // 服务器地址
    serverPort: string        // 服务器端口
    serverProto: string       // 协议
    autologin: boolean        // 是否证书认证
}

OpenVpnProfileDetail

type OpenVpnProfileDetail = {
    id: number
    name: string
    content: string           // .ovpn 完整内容
    serverHost: string
    serverPort: string
    serverProto: string
    autologin: boolean
    username: string
    password: string          // 已脱敏(显示为 ***)
}

OpenVpnLogEntry

type OpenVpnLogEntry = {
    level: string             // 'info' | 'warn' | 'error' | 'debug'
    text: string              // 日志文本
}

回调类型

type OpenVpnStatusCallback = (state: OpenVpnState) => void
type OpenVpnLogCallback = (level: string, text: string) => void
type OpenVpnTrafficCallback = (stats: OpenVpnTrafficStats) => void

💻 代码示例

完整连接流程

import {
    initApp, connect, disconnect, getStatus,
    onStatus, onLog, removeAllListeners,
} from '@/uni_modules/ly028-OpenV'

// 初始化
initApp()

// 监听日志
onLog((level, text) => {
    console.log(`[${level}] ${text}`)
})

// 监听状态
const unsubscribe = onStatus((state) => {
    switch (state) {
        case 'CONNECTED':
            const s = getStatus()
            console.log(`已连接,VPN IP: ${s.vpnIp4}`)
            break
        case 'ERROR':
            console.error('连接失败')
            break
    }
})

// 发起连接
connect({
    content: 'client\ndev tun\nproto udp\nremote vpn.example.com 1194...',
    username: 'user',
    password: 'pass',
})

// 断开
// disconnect()

// 清理
// removeAllListeners()

配置文件管理

import {
    getProfiles, getProfileDetail, saveOrUpdateProfile,
    deleteProfile, evalConfig,
} from '@/uni_modules/ly028-OpenV'

// 评估配置
const result = evalConfig({ content: ovpnText })
if (result.error) {
    uni.showToast({ title: '配置无效: ' + result.message, icon: 'none' })
    return
}

// 保存配置
const id = saveOrUpdateProfile(
    0,                      // id <= 0 表示新建
    result.friendlyName || 'My Config',
    ovpnText,
    result.remoteHost || '',
    result.remotePort || '',
    result.remoteProto || '',
    result.autologin,
    username,
    password,
)

// 获取配置列表
const profiles = getProfiles()
profiles.forEach(p => {
    console.log(`${p.name} — ${p.serverHost}:${p.serverPort} (${p.serverProto})`)
})

// 获取完整详情
const detail = getProfileDetail(1)
if (detail) {
    console.log('完整配置内容:', detail.content)
}

// 删除配置
deleteProfile(1)

实时流量显示

import { onTraffic } from '@/uni_modules/ly028-OpenV'

onTraffic((stats) => {
    const down = formatBytes(stats.speedIn) + '/s'
    const up = formatBytes(stats.speedOut) + '/s'
    const total = formatBytes(stats.bytesIn + stats.bytesOut)
    console.log(`⬇ ${down}  ⬆ ${up}  📦 ${total}`)
})

function formatBytes(bytes: number): string {
    if (!bytes || bytes === 0) return '0 B'
    const units = ['B', 'KB', 'MB', 'GB']
    const i = Math.floor(Math.log(bytes) / Math.log(1024))
    return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + units[i]
}

📝 更新日志

v1.0.0 (2025-06)

  • ✅ 初始发布
  • ✅ Android OpenVPN3 核心集成
  • ✅ 配置文件导入(文件选择 + 粘贴文本)
  • ✅ VPN 连接/断开/重连
  • ✅ 实时状态、日志、流量回调
  • ✅ 多配置管理(保存/编辑/删除)
  • ✅ 前台服务通知栏
  • ✅ 配置持久化
  • ✅ 多语言支持(中文 / English)
  • ✅ Android minSdkVersion 24

⚠️ 合规与法律风险提示

  1. 境内监管:在中华人民共和国境内,未经电信主管部门批准,不得擅自建立、使用非法定信道进行国际联网。集成本插件的应用若用于向公众提供 VPN/代理上网服务,可能涉及违法违规,集成方须自行评估法律风险。
  2. 插件定位:本插件是技术组件,不是上网服务。作者不对集成方的业务用途、用户行为及内容负责。
  3. 用户告知:您的 App 应向用户明确说明:为何申请 VPN、通知等权限;数据如何传输;是否记录日志等(隐私政策)。
  4. 资质要求:若业务涉及增值电信、跨境专线等范畴,请自行办理相应许可或与持证主体合作。
  5. 禁止用途:不得用于攻击、扫描、传播违法信息、规避国家网络监管等。

📄 许可

MIT License

Copyright © 2025 ly027


隐私、权限声明

1. 本插件需要申请的系统权限列表:

Android: INTERNET(网络连接), ACCESS_NETWORK_STATE(网络状态), ACCESS_WIFI_STATE(WiFi状态), FOREGROUND_SERVICE/FOREGROUND_SERVICE_SPECIAL_USE(前台服务保活), POST_NOTIFICATIONS(通知栏), RECEIVE_BOOT_COMPLETED(开机自启), READ_EXTERNAL_STORAGE(≤API32 导入.ovpn), READ_MEDIA_DOCUMENTS(≥API33 导入.ovpn)

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据,配置信息仅本地存储

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率: