# my_native_bridge **Repository Path**: i-os-project/my_native_bridge ## Basic Information - **Project Name**: my_native_bridge - **Description**: flutter 相关插件 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-02 - **Last Updated**: 2026-06-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README cat > /Volumes/wmac/Documents/flutter-p/myapp5/my_native_bridge/README.md << 'EOF' # my_native_bridge 一个 Flutter 插件,用于与原生平台通信,主要提供腾讯定位 SDK 集成、权限管理、IDFA 获取和友盟超链等功能。 **平台支持:** iOS 14.0+ (Android 暂未实现) ## 功能特性 - ✅ 腾讯定位 SDK 初始化和配置 - ✅ 单次定位请求 - ✅ 定位权限检查和请求 - ✅ 获取 iOS 广告标识符(IDFA) - ✅ 完整的错误处理和权限管理 - ✅ 友盟超链(U-Link)集成 - ✅ 获取超链安装参数 ## 安装 由于本插件托管在 Gitee,请在 `pubspec.yaml` 中使用 git 依赖: ```yaml dependencies: my_native_bridge: git: url: https://gitee.com/i-os-project/my_native_bridge.git ref: 1.0.8 # 指定标签,锁定版本 ``` 然后运行: ```bash flutter pub get ``` > **💡 提示**:指定 `ref: 1.0.8` 确保不会受到主分支后续代码改动的影响。如果想跟踪最新开发版本,改为 `ref: main` ## iOS 平台配置 ### 1. Info.plist 权限配置 在 `ios/Runner/Info.plist` 中添加以下权限配置: ```xml NSLocationWhenInUseUsageDescription 应用需要访问您的位置信息以提供更好的服务 NSLocationAlwaysAndWhenInUseUsageDescription 应用需要访问您的位置信息以提供更好的服务 NSUserTrackingUsageDescription 应用需要您的同意来访问您的广告标识符(IDFA) ``` ### 2. Podfile 配置 确保 `ios/Podfile` 中包含腾讯定位 SDK: ```ruby # iOS/Podfile post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) target.build_configurations.each do |config| config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [ '$(inherited)', 'PERMISSION_LOCATION=1', ] end end end ``` ## 使用教程 ### 基础初始化 ```dart import 'package:my_native_bridge/my_native_bridge.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({Key? key}) : super(key: key); @override State createState() => _MyAppState(); } class _MyAppState extends State { final bridge = MyNativeBridge(); @override void initState() { super.initState(); _initPlugin(); } Future _initPlugin() async { // 初始化插件(需要腾讯定位 SDK 的 API Key) final version = await bridge.init(key: '你的腾讯定位API密钥'); print('腾讯定位SDK版本: $version'); // 用户同意隐私协议后调用 await bridge.setUserAgreePrivacy(true); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('my_native_bridge 示例')), body: const LocationDemo(), ), ); } } ``` ### 1️⃣ 检查定位权限 ```dart Future checkPermission() async { final hasPermission = await bridge.checkLocationPermission(); if (hasPermission) { print('✅ 已获得定位权限'); } else { print('❌ 没有定位权限'); // 可以在这里请求权限 await requestPermission(); } } ``` ### 2️⃣ 请求定位权限 ```dart Future requestPermission() async { await bridge.requestLocationPermission(); // 系统会弹出权限申请弹窗 } ``` ### 3️⃣ 获取一次定位 ```dart Future getLocation() async { // 先检查权限 final hasPermission = await bridge.checkLocationPermission(); if (!hasPermission) { print('缺少定位权限,请先请求权限'); return; } try { final location = await bridge.getLocationOnce(); if (location.isEmpty) { print('定位失败'); return; } print('📍 定位成功!'); print('纬度: ${location['latitude']}'); print('经度: ${location['longitude']}'); print('城市: ${location['city']}'); print('地址: ${location['address']}'); print('行政区编码: ${location['adcode']}'); } catch (e) { print('定位异常: $e'); } } ``` ### 4️⃣ 获取设备 IDFA ```dart Future getDeviceIDFA() async { try { final idfa = await bridge.getIDFA(); if (idfa.isEmpty) { print('⚠️ IDFA 为空,可能用户拒绝了权限'); return; } print('📱 您的 IDFA: $idfa'); } catch (e) { print('获取 IDFA 异常: $e'); } } ``` ### 5️⃣ 友盟超链集成 #### 5.1 初始化友盟超链 ```dart Future initUMLink() async { // 先设置用户隐私同意 await bridge.setUserAgreePrivacy(true); // 初始化友盟SDK(同时会初始化超链) await bridge.initUMLink(appKey: '你的友盟AppKey'); print('友盟超链初始化成功'); } ``` #### 5.2 获取超链安装参数 ```dart Future getUMLinkParams() async { final params = await bridge.getUMLinkInstallParams(); if (params != null && params.isNotEmpty) { print('🎯 友盟超链参数: $params'); // 根据参数处理业务逻辑,比如跳转到指定页面 } else { print('没有获取到超链参数'); } } ``` ## 完整使用示例 ```dart import 'package:flutter/material.dart'; import 'package:my_native_bridge/my_native_bridge.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'my_native_bridge 示例', theme: ThemeData(primarySwatch: Colors.blue), home: const LocationDemo(), ); } } class LocationDemo extends StatefulWidget { const LocationDemo({Key? key}) : super(key: key); @override State createState() => _LocationDemoState(); } class _LocationDemoState extends State { final bridge = MyNativeBridge(); String _locationInfo = '📍 点击下方按钮获取定位'; bool _hasPermission = false; bool _isLoading = false; @override void initState() { super.initState(); _initBridge(); } Future _initBridge() async { try { // 初始化腾讯定位 SDK final version = await bridge.init(key: '556BZ-JX4LZ-HBEX5-7BBAG-2IPXO-4ZBJ5'); print('SDK版本: $version'); // 设置用户同意隐私协议 await bridge.setUserAgreePrivacy(true); // 检查初始权限状态 final hasPermission = await bridge.checkLocationPermission(); setState(() { _hasPermission = hasPermission; if (_hasPermission) { _locationInfo = '✅ 已有定位权限,可以获取位置'; } else { _locationInfo = '⚠️ 没有定位权限,请先请求权限'; } }); } catch (e) { setState(() { _locationInfo = '❌ 初始化失败: $e'; }); } } Future _getLocation() async { if (!_hasPermission) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('请先请求定位权限')), ); return; } setState(() { _isLoading = true; _locationInfo = '⏳ 定位中...'; }); try { final location = await bridge.getLocationOnce(); if (location.isEmpty) { setState(() { _locationInfo = '❌ 定位失败,请稍后重试'; _isLoading = false; }); return; } setState(() { _locationInfo = '''📍 定位成功! 纬度: ${location['latitude']} 经度: ${location['longitude']} 城市: ${location['city']} 地址: ${location['address']} 行政区编码: ${location['adcode']}'''; _isLoading = false; }); } catch (e) { setState(() { _locationInfo = '❌ 定位异常: $e'; _isLoading = false; }); } } Future _requestPermission() async { await bridge.requestLocationPermission(); // 延迟检查权限(系统弹窗需要时间关闭) await Future.delayed(const Duration(milliseconds: 500)); final hasPermission = await bridge.checkLocationPermission(); setState(() { _hasPermission = hasPermission; if (_hasPermission) { _locationInfo = '✅ 已获得定位权限!'; } else { _locationInfo = '❌ 权限被拒绝'; } }); } Future _getIDFA() async { try { final idfa = await bridge.getIDFA(); if (idfa.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('IDFA 为空,用户可能拒绝了权限')), ); return; } ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('IDFA: $idfa')), ); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('获取 IDFA 失败: $e')), ); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('定位示例')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( padding: const EdgeInsets.all(24), child: SelectableText( _locationInfo, textAlign: TextAlign.center, style: const TextStyle(fontSize: 16, height: 1.6), ), ), const SizedBox(height: 24), ElevatedButton.icon( onPressed: _isLoading ? null : _getLocation, icon: const Icon(Icons.location_on), label: const Text('获取定位'), ), const SizedBox(height: 12), ElevatedButton.icon( onPressed: _requestPermission, icon: const Icon(Icons.privacy_tip), label: const Text('请求权限'), ), const SizedBox(height: 12), ElevatedButton.icon( onPressed: _getIDFA, icon: const Icon(Icons.phone_iphone), label: const Text('获取 IDFA'), ), ], ), ), ); } } ``` ## API 参考 ### MyNativeBridge 类 | 方法 | 返回值 | 说明 | |------|--------|------| | `getPlatformVersion()` | `Future` | 获取系统版本 | | `init({required String key})` | `Future` | 初始化腾讯定位 SDK,返回版本号 | | `checkLocationPermission()` | `Future` | 检查是否有定位权限 | | `requestLocationPermission()` | `Future` | 弹出系统权限申请对话框 | | `getLocationOnce()` | `Future>` | 执行一次定位 | | `getIDFA()` | `Future` | 获取 iOS 广告标识符 | | `setUserAgreePrivacy(bool)` | `Future` | 设置用户隐私同意状态 | | `initUMLink({required String appKey})` | `Future` | 初始化友盟超链SDK | | `getUMLinkInstallParams()` | `Future?` | 获取友盟超链安装参数 | ### 定位结果字段 `getLocationOnce()` 返回的 Map 包含以下字段: ```dart { 'latitude': double, // 纬度 'longitude': double, // 经度 'city': String, // 城市名称 'address': String, // 详细地址 'adcode': String, // 行政区划代码 } ``` ## 错误处理 所有方法都内置了错误处理,会自动捕获异常并返回默认值: | 方法 | 出错返回值 | |-----|----------| | `getLocationOnce()` | 空 Map `{}` | | `getIDFA()` | 空字符串 `""` | | `checkLocationPermission()` | `false` | | `init()` | 空字符串 `""` | 详细的错误信息会在控制台打印。 ## 常见问题 ### ❓ 定位总是返回空? **可能原因:** 1. 未调用 `init()` 初始化 SDK 2. 没有定位权限(`checkLocationPermission()` 返回 false) 3. `Info.plist` 未配置权限说明 4. API Key 不正确或已过期 **解决方案:** ```dart // 1. 先初始化 await bridge.init(key: '你的API密钥'); // 2. 检查权限 final hasPermission = await bridge.checkLocationPermission(); if (!hasPermission) { await bridge.requestLocationPermission(); } // 3. 再请求定位 final location = await bridge.getLocationOnce(); ``` ### ❓ 获取 IDFA 返回空字符串? **可能原因:** 1. iOS 版本低于 14.0 2. 用户在系统设置中拒绝了 App Tracking 权限 3. 设备的广告追踪功能已禁用 **解决方案:** - 请用户进入 设置 > 隐私 > 广告 > 打开"允许应用请求追踪" - 检查您的应用是否获得了 IDFA 权限 ### ❓ 是否支持 Android? 目前仅 iOS 平台有完整实现,Android 支持正在开发中。 ### ❓ 如何从 main 分支更新到最新版本? 在 `pubspec.yaml` 中修改: ```yaml dependencies: my_native_bridge: git: url: https://gitee.com/i-os-project/my_native_bridge.git ref: main # 或改为其他版本号如 1.0.3 ``` 然后运行 `flutter pub get` ## 更新日志 详见 [CHANGELOG.md](CHANGELOG.md) ## 许可证 待定 ## 反馈 如有问题或建议,欢迎提交 Issue 或 PR 到 [Gitee 仓库](https://gitee.com/i-os-project/my_native_bridge) EOF