Flutter共享链接管理插件fl_shared_link的使用

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

Flutter共享链接管理插件fl_shared_link的使用

本文将详细介绍如何在Flutter项目中使用fl_shared_link插件来管理共享链接。此插件允许用户通过各种应用(如微信、QQ等)分享内容到你的Flutter应用,并能够处理这些分享的回调。

Android配置项

Android MainActivity

首先,我们需要在AndroidManifest.xml文件中注册接收分享的意图过滤器。以下是配置示例:

<activity android:name=".MainActivity">
    ...
    <!-- 注册接收分享 -->
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <!-- 接收分享的文件类型 -->
        <data android:mimeType="application/pdf" />
    </intent-filter>
    <!-- 注册默认打开事件,微信、QQ的其他应用打开 -->
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />

        <data android:scheme="file" />
        <data android:scheme="content" />

        <!-- 接收打开的文件类型 -->
        <data android:mimeType="application/pdf" />
    </intent-filter>
    ...
</activity>

为了支持更多文件类型,可以添加以下配置:

<intent-filter>
    <data android:mimeType="image/*" />
    <data android:mimeType="text/*" />
    <data android:mimeType="application/msword" />
    <data android:mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
    <data android:mimeType="application/vnd.ms-excel" />
    <data android:mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
    <data android:mimeType="application/vnd.ms-powerpoint" />
    <data android:mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation" />
    <data android:mimeType="application/pdf" />
</intent-filter>

使用(Android)

void func() async {
  /// 获取 android 所有 Intent
  /// 获取 Intent for android
  final intent = await FlSharedLink().intentWithAndroid;

  /// 当前获取到intent中的uri中带有文件路径,会自动转换为 文件真实路径 兼容微信或qq
  /// 微信或QQ 此方法会拷贝文件至当前app内部空间
  /// 获取真实文件路径
  final realPath = await FlSharedLink().getRealFilePathWithAndroid(intent.id);

  /// 监听 android 所有的 intent 数据
  FlSharedLink().receiveHandler(onIntent: (AndroidIntentModel? data) {
    /// 监听所有 intent 数据
    /// 获取分享或打开的数据
  });
}

解决Telegram和Email等问题

如果遇到Telegram和Email等问题,可以通过以下步骤解决:

  1. 复制example/android/app/src/main/kotlin/fl/shared/link/example/SharedLauncherActivity.kt文件到你自己app的目录下,与MainActivity在同一个目录。
  2. 添加以下配置到project/android/app/src/main/AndroidManifest.xml文件中:
<activity android:exported="true" android:hardwareAccelerated="true" android:launchMode="singleInstance" android:name=".SharedLauncherActivity" android:theme="@style/LaunchTheme">

    <!-- 注册接收分享 -->
    <intent-filter android:label="SharedLauncher接收">
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <!-- 接收分享的文件类型 -->
        <data android:mimeType="*/*" />
    </intent-filter>

    <!-- 注册默认打开事件,微信、QQ的其他应用打开 -->
    <intent-filter android:label="SharedLauncher打开">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />

        <data android:scheme="file" />
        <data android:scheme="content" />
        <!-- 接收打开的文件类型 -->
        <data android:mimeType="*/*" />
    </intent-filter>
</activity>
  1. 请移除MainActivity中的相同的intent-filter配置,以避免在分享列表中出现两个自己的app。

注意:从不同浏览器和来源打开文件时,可能会每次启动一个新的应用实例。为了避免这种情况,更新AndroidManifest.xml文件中的android:launchMode属性为android:launchMode="singleInstancePerTask"

iOS配置项

iOS Info.plist

Info.plist文件中添加以下配置:

<key>LSSupportsOpeningDocumentsInPlace</key>
<string>No</string>
<key>CFBundleDocumentTypes</key>
<array>
    <dict>
        <key>CFBundleTypeName</key>
        <string>FlSharedLink</string>
        <key>LSHandlerRank</key>
        <string>Default</string>
        <key>LSItemContentTypes</key>
        <array>
            <string>public.file-url</string>
            <string>public.image</string>
            <string>public.text</string>
            <string>public.movie</string>
            <string>public.url</string>
            <string>public.data</string>
        </array>
    </dict>
</array>

使用(iOS)

void func() async {
  /// 通过universalLink启动app获取上一次启动携带的参数
  /// 通常 微信分享qq分享返回app中
  final universalLink = await FlSharedLink().universalLinkWithIOS;

  /// 通过openUrl或handleOpenUrl启动app获取上一个启动携带的参数
  /// 通常 用 其他应用打开 分享 或 打开 携带的参数从这里获取
  final openUrl = await FlSharedLink().openUrlWithIOS;

  /// app首次启动 获取启动参数
  final Map? launchingOptionsWithIOS = await FlSharedLink().launchingOptionsWithIOS;

  FlSharedLink().receiveHandler(
      onUniversalLink: (IOSUniversalLinkModel? data) {
        /// 监听通过 universalLink 打开app 回调以及参数
      },
      onOpenUrl: (IOSOpenUrlModel? data) {
        /// 监听通过 openUrl或者handleOpenUrl 打开app 回调以及参数
      });
}

示例代码

以下是完整的示例代码:

import 'package:fl_shared_link/fl_shared_link.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

bool get _isAndroid => defaultTargetPlatform == TargetPlatform.android;

bool get _isIOS => defaultTargetPlatform == TargetPlatform.iOS;

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
          appBar: AppBar(title: const Text('FlSharedLink Plugin')),
          body: Container(
              alignment: Alignment.center,
              padding: const EdgeInsets.all(20),
              child: const SingleChildScrollView(child: HomePage())))));
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  [@override](/user/override)
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  IOSUniversalLinkModel? universalLink;
  IOSOpenUrlModel? openUrl;
  Map? launchingOptionsWithIOS;
  AndroidIntentModel? intent;
  String? realPath;

  [@override](/user/override)
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) async {
      if (_isIOS) {
        universalLink = await FlSharedLink().universalLinkWithIOS;
        openUrl = await FlSharedLink().openUrlWithIOS;
        launchingOptionsWithIOS = await FlSharedLink().launchingOptionsWithIOS;
      }
      if (_isAndroid) intent = await FlSharedLink().intentWithAndroid;
      setState(() {});
      FlSharedLink().receiveHandler(
          onUniversalLink: (IOSUniversalLinkModel? data) {
        universalLink = data;
        setState(() {});
      }, onOpenUrl: (IOSOpenUrlModel? data) {
        openUrl = data;
        setState(() {});
      }, onIntent: (AndroidIntentModel? data) {
        intent = data;
        setState(() {});
      });
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    List<Widget> children = [];
    if (_isAndroid) children = androidChildren;
    if (_isIOS) children = iosChildren;
    return Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: children);
  }

  List<Widget> get androidChildren => [
        const Text('Android Intent'),
        const SizedBox(height: 10),
        Container(
            width: double.infinity,
            padding: const EdgeInsets.all(12),
            margin: const EdgeInsets.all(12),
            alignment: Alignment.center,
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(8),
                color: Colors.grey.withOpacity(0.3)),
            child: Text('${intent?.toMap()}')),
        const SizedBox(height: 10),
        ElevatedButton(
            onPressed: getRealFilePathWithAndroid,
            child: const Text('Android uri转真实文件地址 兼容微信QQ')),
        const SizedBox(height: 10),
        Container(
            width: double.infinity,
            padding: const EdgeInsets.all(12),
            margin: const EdgeInsets.all(12),
            alignment: Alignment.center,
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(8),
                color: Colors.grey.withOpacity(0.3)),
            child: Text(realPath.toString())),
        const SizedBox(height: 30),
      ];

  void getRealFilePathWithAndroid() async {
    final id = intent?.id;
    if (id == null) return;
    realPath = await FlSharedLink().getRealFilePathWithAndroid(id);
    setState(() {});
  }

  List<Widget> get iosChildren => [
        const Text('IOS Launching Options'),
        const SizedBox(height: 10),
        Container(
            width: double.infinity,
            padding: const EdgeInsets.all(12),
            margin: const EdgeInsets.all(12),
            alignment: Alignment.center,
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(8),
                color: Colors.grey.withOpacity(0.3)),
            child: Text('$launchingOptionsWithIOS')),
        const SizedBox(height: 10),
        const Text('IOS UniversalLink'),
        const SizedBox(height: 10),
        Container(
            width: double.infinity,
            padding: const EdgeInsets.all(12),
            margin: const EdgeInsets.all(12),
            alignment: Alignment.center,
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(8),
                color: Colors.grey.withOpacity(0.3)),
            child: Text('${universalLink?.toMap()}')),
        const SizedBox(height: 10),
        const Text('IOS openUrl'),
        const SizedBox(height: 10),
        Container(
            width: double.infinity,
            padding: const EdgeInsets.all(12),
            margin: const EdgeInsets.all(12),
            alignment: Alignment.center,
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(8),
                color: Colors.grey.withOpacity(0.3)),
            child: Text('${openUrl?.toMap()}')),
        const SizedBox(height: 30),
      ];
}

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

1 回复

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


当然,以下是如何在Flutter项目中使用fl_shared_link插件来管理共享链接的一个基本示例。请注意,由于fl_shared_link可能不是一个实际存在的Flutter插件(在撰写时我未能在pub.dev上找到它),我将提供一个类似功能的示例,使用Flutter的share插件和URL处理来模拟共享链接的管理。

首先,确保你已经在pubspec.yaml文件中添加了share插件:

dependencies:
  flutter:
    sdk: flutter
  share: ^0.6.5+3  # 请检查最新版本号

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

接下来,在你的Flutter项目中创建一个简单的界面来生成和分享链接。以下是一个示例代码:

import 'package:flutter/material.dart';
import 'package:share/share.dart';
import 'package:url_launcher/url_launcher.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Share Link Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ShareLinkScreen(),
    );
  }
}

class ShareLinkScreen extends StatefulWidget {
  @override
  _ShareLinkScreenState createState() => _ShareLinkScreenState();
}

class _ShareLinkScreenState extends State<ShareLinkScreen> {
  final String shareLink = 'https://example.com/shared-link';

  void _share() async {
    final RenderBox box = context.findRenderObject();
    await Share.share(shareLink,
        sharePositionOrigin: box.localToGlobal(Offset.zero) & box.size);
  }

  void _launchURL() async {
    if (await canLaunch(shareLink)) {
      await launch(shareLink);
    } else {
      throw 'Could not launch $shareLink';
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Share Link Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Here is your share link:',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 20),
            SelectableText(
              shareLink,
              style: TextStyle(fontSize: 18, color: Colors.blue, decoration: TextDecoration.underline),
              onSelected: (String text) {
                _launchURL();
              },
            ),
            SizedBox(height: 40),
            ElevatedButton(
              onPressed: _share,
              child: Text('Share Link'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们做了以下几件事:

  1. 依赖管理:在pubspec.yaml中添加了share插件。
  2. UI设计:创建了一个简单的UI,包含一个要分享的链接和一个按钮。
  3. 分享功能:使用Share.share方法分享链接。
  4. 链接打开功能:使用url_launcher插件的launch方法打开链接(注意:需要额外添加url_launcher依赖,并处理可能的异常)。

为了处理URL打开功能,你还需要在pubspec.yaml中添加url_launcher依赖:

dependencies:
  url_launcher: ^6.0.3  # 请检查最新版本号

然后,再次运行flutter pub get

这个示例展示了如何使用Flutter的插件来管理和分享链接。如果你确实在寻找一个名为fl_shared_link的特定插件,并且它在pub.dev上存在,那么使用方法可能会有所不同,但基本的思路是相似的:使用插件提供的功能来生成、分享和处理链接。

回到顶部