Flutter共享链接管理插件fl_shared_link的使用
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等问题,可以通过以下步骤解决:
- 复制
example/android/app/src/main/kotlin/fl/shared/link/example/SharedLauncherActivity.kt
文件到你自己app的目录下,与MainActivity
在同一个目录。 - 添加以下配置到
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>
- 请移除
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
更多关于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'),
),
],
),
),
);
}
}
在这个示例中,我们做了以下几件事:
- 依赖管理:在
pubspec.yaml
中添加了share
插件。 - UI设计:创建了一个简单的UI,包含一个要分享的链接和一个按钮。
- 分享功能:使用
Share.share
方法分享链接。 - 链接打开功能:使用
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上存在,那么使用方法可能会有所不同,但基本的思路是相似的:使用插件提供的功能来生成、分享和处理链接。