Flutter统一链接处理插件uni_links3的使用

发布于 1周前 作者 ionicwang 来自 Flutter

Flutter统一链接处理插件uni_links3的使用

简介

uni_links 是一个Flutter插件项目,用于处理App/Deep Links(Android)和Universal Links及Custom URL schemes(iOS)。这些链接类似于网页浏览器中的链接,可以激活您的应用程序,并可能包含您用来加载特定部分或继续某些用户活动的信息。

安装

添加依赖

pubspec.yaml 文件中添加 uni_links 依赖:

dependencies:
  flutter:
    sdk: flutter
  uni_links: ^0.5.1

权限配置

Android

android/app/src/main/AndroidManifest.xml 中声明意图过滤器:

Deep Links

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="[YOUR_SCHEME]" android:host="[YOUR_HOST]" />
</intent-filter>

App Links

<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="https" android:host="[YOUR_HOST]" />
</intent-filter>

iOS

ios/Runner/Info.plist 中声明URL类型:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLName</key>
        <string>[ANY_URL_NAME]</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>[YOUR_SCHEME]</string>
        </array>
    </dict>
</array>

或者通过Xcode设置关联域:

  1. 打开 ios/Runner.xcworkspace
  2. 在项目导航器中选择 Runner 根项。
  3. 选择 Signing & Capabilities 选项卡,点击 + Capability 按钮。
  4. 添加 Associated Domains 并输入你的域名,如 applinks:[YOUR_HOST]

使用示例

初始化链接处理

在应用启动时初始化链接处理:

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

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Uri? _initialUri;
  Uri? _latestUri;
  Object? _err;

  StreamSubscription? _sub;

  @override
  void initState() {
    super.initState();
    _handleIncomingLinks();
    _handleInitialUri();
  }

  @override
  void dispose() {
    _sub?.cancel();
    super.dispose();
  }

  void _handleIncomingLinks() {
    if (!kIsWeb) {
      _sub = uriLinkStream.listen((Uri? uri) {
        if (!mounted) return;
        setState(() {
          _latestUri = uri;
          _err = null;
        });
      }, onError: (Object err) {
        if (!mounted) return;
        setState(() {
          _latestUri = null;
          if (err is FormatException) {
            _err = err;
          } else {
            _err = null;
          }
        });
      });
    }
  }

  Future<void> _handleInitialUri() async {
    try {
      final uri = await getInitialUri();
      if (uri == null) {
        print('no initial uri');
      } else {
        print('got initial uri: $uri');
      }
      if (!mounted) return;
      setState(() => _initialUri = uri);
    } on PlatformException {
      print('falied to get initial uri');
    } on FormatException catch (err) {
      if (!mounted) return;
      setState(() => _err = err);
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('uni_links example app')),
        body: ListView(
          children: [
            ListTile(
              title: const Text('Initial Uri'),
              subtitle: Text('$_initialUri'),
            ),
            ListTile(
              title: const Text('Latest Uri'),
              subtitle: Text('$_latestUri'),
            ),
          ],
        ),
      ),
    );
  }
}

测试链接

在终端中运行以下命令来测试链接:

  • Android:
    adb shell 'am start -W -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d "unilinks://host/path/subpath"'
    
  • iOS:
    /usr/bin/xcrun simctl openurl booted "unilinks://host/path/subpath"
    

更多关于Flutter统一链接处理插件uni_links3的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter统一链接处理插件uni_links3的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用uni_links3插件来统一处理链接(deep linking)的一个示例。这个插件可以帮助你捕获和处理从浏览器、其他应用或邮件等点击的链接。

步骤 1: 添加依赖

首先,你需要在pubspec.yaml文件中添加uni_links3依赖:

dependencies:
  flutter:
    sdk: flutter
  uni_links3: ^0.5.0  # 请注意版本号,使用最新版本

然后运行flutter pub get来安装依赖。

步骤 2: 配置AndroidManifest.xml

在Android项目中,你需要在AndroidManifest.xml中添加必要的intent-filter来捕获链接。例如,如果你想要捕获以https://example.com开头的链接,可以这样做:

<activity
    android:name=".MainActivity"
    android:launchMode="singleTop"
    android:theme="@style/LaunchTheme"
    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|screenLayout|density|uiMode"
    android:hardwareAccelerated="true"
    android:windowSoftInputMode="adjustResize">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="https" android:host="example.com" />
    </intent-filter>
</activity>

步骤 3: 配置iOS Info.plist

在iOS项目中,你需要在Info.plist中添加URL Types来捕获链接。例如:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>yourappscheme</string>
        </array>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
    </dict>
    <dict>
        <key>CFBundleURLName</key>
        <string>com.example.yourapp</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>https</string>
        </array>
    </dict>
</array>

注意:对于HTTPS链接,iOS的配置可能比较复杂,通常需要配合Universal Links或App Links,这里仅展示基本的配置。

步骤 4: 在Flutter代码中处理链接

在你的Flutter项目中,你可以使用uni_links3插件来监听和处理链接。以下是一个示例代码:

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

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String? _latestLink;

  @override
  void initState() {
    super.initState();
    // 监听链接变化
    _initUniLinks();
  }

  Future<void> _initUniLinks() async {
    // 获取初始链接(如果有的话)
    final InitialLinkEvent? initialLink = await getInitialLink();
    if (initialLink?.link != null) {
      setState(() {
        _latestLink = initialLink!.link!;
      });
    }

    // 监听链接变化
    subscribeToLinks((LinkEvent link) {
      setState(() {
        // 更新最新的链接
        _latestLink = link.link;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Uni Links Demo'),
        ),
        body: Center(
          child: _latestLink == null
              ? Text('No link received')
              : Text('Received link: $_latestLink'),
        ),
      ),
    );
  }
}

这个示例展示了如何初始化uni_links3插件,获取初始链接,并监听后续的链接变化。当应用接收到链接时,它会更新UI以显示最新的链接。

请确保你已经正确配置了Android和iOS项目,以便能够捕获和处理链接。在实际项目中,你可能还需要处理更多的链接类型和错误情况。

回到顶部