Flutter VPN配置管理插件flutter_openvpn的使用

flutter_openvpn概述

flutter_openvpn 是一个基于 Flutter 的插件,用于管理和控制 OpenVPN 连接。通过此插件,您可以轻松地在 Flutter 应用中实现 OpenVPN 配置的加载与连接。


安装flutter_openvpn

1. 添加依赖

将以下内容添加到 pubspec.yaml 文件中:

dependencies:
  flutter_openvpn: ^0.2.0

2. 安装依赖

在终端运行以下命令以安装依赖:

$ flutter pub get

3. 导入插件

在 Dart 文件中导入插件:

import 'package:flutter_openvpn/flutter_openvpn.dart';

支持的平台

  • Android: API 级别 22 及以上
  • iOS: iOS 9.0 及以上

构建项目

1. 构建 APK 或 iOS 应用

运行以下命令构建项目:

对于 Android:

flutter build apk --debug

对于 iOS:

flutter build ios --no-codesign

忽略任何构建错误。


Android 集成

1. 修改最小 SDK 版本

确保 Android 项目的最低 SDK 版本为 22。

2. 修改 MainActivity

打开 MainActivity.javaMainActivity.kt 文件,并添加以下代码:

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 1) {
        if (resultCode == RESULT_OK) {
            FlutterOpenvpnPlugin.setPermission(true);
        } else {
            FlutterOpenvpnPlugin.setPermission(false);
        }
    }
}

3. 导入插件

在文件顶部添加以下导入语句:

import com.topfreelancerdeveloper.flutter_openvpn.FlutterOpenvpnPlugin;

iOS 集成

1. 添加 VPN 权限

在 Xcode 中执行以下步骤:

  1. 打开 ios/Runner.xcworkspace
  2. Runner 目标中,进入 Signing & Capabilities,点击 + Capability
  3. 添加 “Network Extension” 和 “App Groups” 功能。
  4. 在 “Network Extension” 菜单中仅选择 “Packet Tunnel”。
  5. 确保 Bundle Identifier 已启用在 “App Groups” 中。
  6. 查看此截图作为参考。

2. 添加网络扩展目标

  1. Runner 目标下点击 “+” 按钮以添加新目标。
  2. 搜索并选择 “Network Extension”。
  3. 设置名称(无空格),语言为 Swift,提供者类型为 “Packet Tunnel”。
  4. 点击完成并同意相关消息。
  5. 对新创建的目标重复 “添加 VPN 权限”。
  6. 查看此截图作为参考。

3. 修改最低平台版本

Runner 和 VPN 扩展的目标最低平台版本设置为 iOS 9.0。

4. 添加 OpenVPNAdapter 依赖

编辑 ios/Podfile 文件并添加以下内容:

target 'Runner' do
  use_frameworks!
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

// 添加以下部分
target 'YOUR_TARGET_EXTENSION_NAME' do
  use_frameworks!
  use_modular_headers!
  pod 'OpenVPNAdapter', :git => 'https://github.com/ss-abramchuk/OpenVPNAdapter.git', :tag => '0.7.0'
end

然后运行以下命令:

$ cd ios
$ pod install

5. 禁用 Bitcode

在 VPN 扩展目标的 Build Settings 中搜索 “Bitcode” 并将其设置为 NO

6. 修改 PacketTunnelProvider

打开 VPNExtension/PacketTunnelProvider.swift 文件并替换所有代码为此代码


Dart/Flutter 集成

1. 初始化插件

调用以下方法初始化插件:

FlutterOpenvpn.init(
  localizedDescription: "ExampleVPN", // iOS 必填字段
  providerBundleIdentifier: "com.topfreelancerdeveloper.flutterOpenvpnExample.RunnerExtension", // iOS 必填字段
  // localizedDescription 是你的 VPN 配置文件名称
  // providerBundleIdentifier 是你的 VPN 扩展包 ID
);

如果成功,返回值包含以下信息:

{
  "currentStatus": "VPN_CURRENT_STATUS",
  "expireAt": "VPN_EXPIRE_DATE_STRING_IN_FORMAT(yyyy-MM-dd HH:mm:ss)"
}

如果失败,返回 null

2. 加载并启动 VPN

调用以下方法加载并启动 VPN:

FlutterOpenvpn.lunchVpn(
  ovpnFileContent, // .ovpn 文件内容
  (isProfileLoaded) => print('isProfileLoaded : $isProfileLoaded'), // 配置加载回调
  (newVpnStatus) => print('vpnActivated : $newVpnStatus'), // 状态变化回调
  user: 'user', // 用户名(可选)
  pass: 'pass', // 密码(可选)
  onConnectionStatusChanged: (duration, lastPacketRecieve, byteIn, byteOut) => print(byteIn), // 连接状态回调
  expireAt: DateTime.now().add(Duration(seconds: 30)), // 自动断开时间(可选)
);

发布到 Google Play 和 App Store

1. Android

  • 使用 .apk 文件发布到 Google Play。
  • 查看此问题以了解相关更新。

2. iOS

  • 查看Apple 指南了解相关规则。
  • 此插件使用的是免许可加密。

示例代码

以下是完整的示例代码:

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter_openvpn/flutter_openvpn.dart';
import 'package:flutter_openvpn_example/newPage.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  static Future<void> initPlatformState() async {
    await FlutterOpenvpn.lunchVpn(
      "SAMPLE_OVPN_FILE",
      (isProfileLoaded) {
        print('isProfileLoaded : $isProfileLoaded');
      },
      (vpnActivated) {
        print('vpnActivated : $vpnActivated');
      },
      user: 'user',
      pass: 'pass',
      onConnectionStatusChanged: (duration, lastPacketRecieve, byteIn, byteOut) =>
          print(byteIn),
      expireAt: DateTime.now().add(
        Duration(
          seconds: 180,
        ),
      ),
    );
  }

  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      onGenerateRoute: (settings) =>
          MaterialPageRoute(
              builder: (context) =>
                  NewPAge(
                      settings.name.contains(NewPAge.subPath)
                          ? settings.name.split(NewPAge.subPath)[1]
                          : '0',
                      settings.name.split(NewPAge.subPath)[1].compareTo('2') < 0),
              settings: settings),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: NewPAge('0', true),
      ),
    );
  }
}

更多关于Flutter VPN配置管理插件flutter_openvpn的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter VPN配置管理插件flutter_openvpn的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


flutter_openvpn 是一个用于在 Flutter 应用中集成和管理 OpenVPN 配置的插件。它允许你在应用中启动、停止和管理 VPN 连接。以下是如何使用 flutter_openvpn 插件的基本步骤:

1. 添加依赖

首先,在你的 pubspec.yaml 文件中添加 flutter_openvpn 依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_openvpn: ^1.0.0  # 请确认使用最新版本

然后运行 flutter pub get 来获取依赖。

2. 配置 Android 和 iOS 项目

Android

android/app/src/main/AndroidManifest.xml 文件中添加以下权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

iOS

ios/Runner/Info.plist 文件中添加以下权限:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
<key>NSVPNConfigurationUsageDescription</key>
<string>We need VPN to secure your connection</string>

3. 使用 flutter_openvpn 插件

在你的 Dart 代码中导入 flutter_openvpn 并开始使用它。

import 'package:flutter/material.dart';
import 'package:flutter_openvpn/flutter_openvpn.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: VPNPage(),
    );
  }
}

class VPNPage extends StatefulWidget {
  @override
  _VPNPageState createState() => _VPNPageState();
}

class _VPNPageState extends State<VPNPage> {
  bool _isConnected = false;

  @override
  void initState() {
    super.initState();
    FlutterOpenvpn.init();
  }

  Future<void> _connectVPN() async {
    try {
      await FlutterOpenvpn.lunchVPN(
        config: 'path_to_your_ovpn_file.ovpn',
        username: 'your_username',
        password: 'your_password',
      );
      setState(() {
        _isConnected = true;
      });
    } catch (e) {
      print('Error connecting to VPN: $e');
    }
  }

  Future<void> _disconnectVPN() async {
    try {
      await FlutterOpenvpn.stopVPN();
      setState(() {
        _isConnected = false;
      });
    } catch (e) {
      print('Error disconnecting from VPN: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter OpenVPN Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _isConnected
                ? Text('VPN Connected')
                : Text('VPN Disconnected'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _isConnected ? _disconnectVPN : _connectVPN,
              child: Text(_isConnected ? 'Disconnect' : 'Connect'),
            ),
          ],
        ),
      ),
    );
  }
}

4. 处理 VPN 状态

你可以监听 VPN 连接状态的变化:

FlutterOpenvpn.onStateChanged.listen((vpnState) {
  print('VPN State: $vpnState');
  if (vpnState == FlutterVpnState.connected) {
    setState(() {
      _isConnected = true;
    });
  } else if (vpnState == FlutterVpnState.disconnected) {
    setState(() {
      _isConnected = false;
    });
  }
});
回到顶部