通过外部链接启动 Flutter App(详细介绍及示例)

通过外部链接启动 Flutter App(firebase_dynamic_links 和 app_links)

详细介绍 通过外部链接启动flutter App 的使用及示例

在我们的APP中,经常有点击链接启动并进入APP的需求(如果未安装跳转到应用商店)。Android通过deep link或者app link(是deep link 的增强版),iOS通过 url schema,可以打开对应的app,因此我们需要对我们的app进行对应的配置。下面将会详细介绍两种方式。
推荐使用app_link

一、firebase_dynamic_links (该服务已经弃用,2025 年 8 月将关闭)

该三方服务提供了 生成分享链接、通过链接启动跳转到指定页面的方法,通知支持 未安装App的时候跳转其他的链接(例如跳转到应用商店),重定向逻辑 由 Firebase 服务自动处理,并且支持短链接。

实现步骤:

1. 安装依赖:

在 pubspec.yaml 文件中添加:

dependencies:flutter:sdk: flutterfirebase_dynamic_links: ^6.0.5

2. 配置 Android

在 android/app/src/main/AndroidManifest.xml 文件中,添加 intent-filter 配置,以便在 Android 中处理 App Links。

<activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.VIEW" /><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.BROWSABLE" /><dataandroid:host="i89trillion.page.link"android:scheme="https" /></intent-filter>
</activity>

3. 初始化链接监听 || 生成分享链接(代码实现)

  • 先在main方法中初始化监听:(在 runApp 之前初始化)
// 初始化动态链接
await FirebaseDynamicLinkService.initDynamicLink();
  • 实现生成分享链接和监听链接的方法:
    示例如下:

import "dart:async";
import "dart:io";import "package:easy_localization/easy_localization.dart";
import "package:firebase_dynamic_links/firebase_dynamic_links.dart";class FirebaseDynamicLinkService {static Duration maxDuration = Duration(seconds: 5);static Future<void> initDynamicLink() async {// 未启动的时候监听final PendingDynamicLinkData? initialLink =await FirebaseDynamicLinks.instance.getInitialLink();if (initialLink != null) {final Uri deepLink = initialLink.link;FirebaseAnalyticsService.logEvent(FirebaseAnalyticsEvent.link_join_guild_finish, '0');_handleDeepLink(deepLink);}// 应用程序在后台启动时有效FirebaseDynamicLinks.instance.onLink.listen((dynamicLinkData) {final Uri deepLink = dynamicLinkData.link;FirebaseAnalyticsService.logEvent(FirebaseAnalyticsEvent.link_join_guild_finish, '1');_handleDeepLink(deepLink);}, onError: (e) {LogUtil.error(e.toString());});}static void _handleDeepLink(Uri deepLink) async {var isJoinGuildLink = deepLink.pathSegments.contains('joinServer');if (isJoinGuildLink) {String? id = deepLink.queryParameters['id'];if (id != null) {LogUtil.info("deepLink serverId: $id");}}}// 创建一个群邀请链接static Future<String> createJoinServerDynamicLink(bool short, int guildID) async {if (!Platform.isAndroid && !Platform.isIOS) {return "该功能只在 Android 和 iOS 上可用";}String _linkMessage;final DynamicLinkParameters parameters = DynamicLinkParameters(uriPrefix: "https://xxx.page.link",link: Uri.parse('https://xxx.page.link/joinServer?id=$guildID'),androidParameters: AndroidParameters(// 未安装应用程序打开的链接fallbackUrl: Uri.parse('https://play.google.com/store/apps/details?id=xxx'),packageName: 'xxx',),);Uri url;if (short) {final ShortDynamicLink shortLink = await FirebaseDynamicLinksPlatform.instance.buildShortLink(parameters);url = shortLink.shortUrl;} else {url = await FirebaseDynamicLinksPlatform.instance.buildLink(parameters);}_linkMessage = url.toString();return _linkMessage;}
}

4. 未安装时跳转

在生成链接的时候参数 fallbackUrl 为未安装App时打开的链接,firebase 服务自己做了重定向。

二、app_links

该三方库 也支持 通过链接启动App,同时解析链接参数,跳转指定页面,但是不支持App未安装的时候跳转其他链接(需要自己的服务处理重定向)
官方文档见:https://developer.android.com/studio/write/app-link-indexing?hl=zh-cn#testindent

实现步骤:

1. 安装依赖:

在 pubspec.yaml 文件中添加:

dependencies:flutter:sdk: flutterapp_links: ^6.0.1 # 用于处理动态链接

2. 配置 Android 和 iOS 支持

在 android/app/src/main/AndroidManifest.xml 文件中,添加 intent-filter 配置,以便在 Android 中处理 App Links。

<activity android:name=".MainActivity"><!-- Add the intent-filter for handling 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="yourapp.page.link" android:pathPrefix="/joinServer"/></intent-filter>
</activity>

注意: 这里注意下,开启autoVerify的activity中的<intent-filter…>的action必须为android.intent.action.VIEW,category必须包含android.intent.category.BROWSABLE,data的scheme必须包含http/https,否则不生效,而且AppLinks必须在Android 6.0 以上的手机才可生效。
android:host 为域名,android:pathPrefix为地址前缀,根据实际需求配置

2. 初始化链接监听 || 生成分享链接(代码实现)

  • 先在main方法中初始化监听:(在 runApp 之前初始化)
// 初始化动态链接await AppLinkService.initializeDynamicLinks();
  • 实现生成分享链接和监听链接的方法:
    示例如下:
import 'package:app_links/app_links.dart';
import "package:beehive/utils/logger.dart";
import "dart:async";class AppLinkService {static final AppLinks appLinks = AppLinks();// 初始化动态链接static Future<void> initializeDynamicLinks() async {print('Initializing dynamic links...');// 监听动态链接流appLinks.uriLinkStream.listen((Uri? uri) {print("appLink listen: $uri");if (uri != null) {_handleDeepLink(uri);}});}// 处理动态链接,跳转到相应页面static void _handleDeepLink(Uri deepLink) async {var isJoinGuildLink = deepLink.pathSegments.contains('joinServer');if (!isJoinGuildLink){return;}String? id = deepLink.queryParameters['id'];LogUtil.info("appLink serverId: $id");}// 生成分享链接static Future<String> generateShareLink(int serverId) async {final String deepLinkUrl = 'https://yourapp.page.link/joinServer?id=$serverId';final Uri dynamicLink = Uri.parse(deepLinkUrl);return dynamicLink.toString(); // 返回生成的动态链接}
}

3. 链接识别启动进App

需要在域名<https://yourapp.page.link> 根目录下面 放一个JSON文件:.well-known/assetlinks.json 。该JSON文件就是用于识别进入App的,如果是谷歌商店的App,可以直接在管理中心生成,如果是测试,就自己生成。
内容格式如下:
[{"relation": ["delegate_permission/common.handle_all_urls"],"target": {"namespace": "android_app","package_name": "xxxx","sha256_cert_fingerprints":["7F:48:F9:..."]}}
]

4. 未安装时跳转逻辑

app link没有实现未安装跳转其他URL,需要自己在自己的服务域名下面进行重定向处理。(例如重定向到应用商店)
快速的方法:将 一个重定向的HTML也放到域名根目录下面。客户端 识别链接就是这个html,可以在链接中加参数。分享链接就是:https://yourapp.page.link/applink.html
例如:applink.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title>App Link</title>
</head>
<script>window.onload = function() {if (/(android)/i.test(navigator.userAgent)) {// 用户使用的是 Android 设备window.location.href = "https://play.google.com/store/apps/details?id=xxx";} else if (/(iphone|ipad|ipod|ios)/i.test(navigator.userAgent)) {// 用户使用的是 iOS 设备window.location.href = "https://itunes.apple.com/app/idxxx";} else {// 用户使用的是其他设备console.log("This device is not supported.");}};
</script>
<body></body>
</html>

也可以在该域名对应的服务中对某个接口实现重定向逻辑:
例如:(go语言 gframe框架为例)

func (ctrl *linkCtrl) LinkRedirect(r *ghttp.Request) {userAgent := r.Header.Get("User-Agent")log.LogRuntime(log.LEVEL_INFO, "[LinkRedirect] userAgent:", userAgent)if strings.Contains(strings.ToLower(userAgent), "android") {// 用户使用的是 Android 设备r.Response.RedirectTo(define.GooglePlayAdd)} else {// 用户使用的是其他设备r.Response.Write("This device is not supported.")}
}

或者也可以直接在NGINX上面重定向跳转.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/1704.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Redis】初识Redis

目录 Redis简介 Redis在内存中存储数据 Redis数据库中的应用 Redis缓存中的应用 Redis消息中间件 尾言 Redis简介 如下是Redis官网中&#xff0c;对Redis的一段描述 在这段描述中&#xff0c;我们提取如下关键要点&#xff1a; Redis主要用于在内存中存储数据Redis可…

IDEA的Git界面(ALT+9)log选项不显示问题小记

IDEA的Git界面ALT9 log选项不显示问题 当前问题idea中log界面什么都不显示其他选项界面正常通过命令查询git日志正常 预期效果解决办法1. 检查 IDEA 的 Git 设置2. 刷新 Git Log (什么都没有大概率是刷新不了)3. 检查分支和日志是否存在4. 清理 IDEA 缓存 (我用这个成功解决)✅…

赤店商城系统点餐小程序多门店分销APP共享股东h5源码saas账号独立版全插件全开源

代码介绍 后端编程语言采用&#xff1a;PHP yii2.0框架 前端代码采用&#xff1a;UNIAPP框架环境要求 推荐选择服务器配置&#xff1a;2核4G内存3M带宽 linux操作系统 控制面板&#xff1a;宝塔面板 运行环境&#xff1a;PHP7.2MYSQL5.7 赤店商城系统是一款集点餐小程序、多门…

穷举vs暴搜vs深搜vs回溯vs剪枝系列一>优美的排列

题目&#xff1a; 解析&#xff1a; 部分决策树&#xff1a; 代码设计&#xff1a; 代码&#xff1a; private int count;private boolean[] check;public int countArrangement(int n) {check new boolean[n1];dfs(n,1);return count;} private void dfs(int n, int pos){…

【C++图论 拓扑排序】2392. 给定条件下构造矩阵|1960

本文涉及知识点 C图论 拓扑排序 LeetCode2392. 给定条件下构造矩阵 给你一个 正 整数 k &#xff0c;同时给你&#xff1a; 一个大小为 n 的二维整数数组 rowConditions &#xff0c;其中 rowConditions[i] [abovei, belowi] 和 一个大小为 m 的二维整数数组 colConditions…

Anaconda安装(2024最新版)

安装新的anaconda需要卸载干净上一个版本的anaconda&#xff0c;不然可能会在新版本安装过程或者后续使用过程中出错&#xff0c;完全卸载干净anaconda的方法&#xff0c;可以参考我的博客&#xff01; 第一步&#xff1a;下载anaconda安装包 官网&#xff1a;Anaconda | The O…

SSE部署后无法连接问题解决

1. 问题现象 通过域名访问 https://api-uat.sfxs.com/sse/subscribe?tokenBearer%20eyJUxMiJ9.eyJhY2NvdW50IjoiYWRtaWZ0NvZGUiOiIwMDEiLCJyb2xidXNlcm5hbWUiOiLotoXnuqfnrqHnkIblkZgifQ.tlz9N61Y4 一直无法正常连接 2. 问题解决 nginx.conf进行配置 server {location /ss…

【优选算法篇】:分而治之--揭秘分治算法的魅力与实战应用

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页&#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏&#xff1a;优选算法篇–CSDN博客 文章目录 一.什么是分治算法1.分治算法的基本概念2.分治算法的三个步…

Unreal Engine 5 C++ Advanced Action RPG 八章笔记

第八章 Boss Enemy 2-Set Up Boss Character 创建Boss敌人流程 起始的数据UI战斗能力行为树 这集新建Boss敌人的蓝图与动画蓝图和混合空间,看看就行巨人在关卡中,它的影子被打破,更改当前项目中的使用的阴影贴图就可以解决 从虚拟阴影贴图更改为阴影贴图即可 3-Giant Start…

C#,图论与图算法,输出无向图“欧拉路径”的弗勒里(Fleury Algorithm)算法和源程序

1 欧拉路径 欧拉路径是图中每一条边只访问一次的路径。欧拉回路是在同一顶点上开始和结束的欧拉路径。 这里展示一种输出欧拉路径或回路的算法。 以下是Fleury用于打印欧拉轨迹或循环的算法&#xff08;源&#xff09;。 1、确保图形有0个或2个奇数顶点。2、如果有0个奇数顶…

day08_Kafka

文章目录 day08_Kafka课程笔记一、今日课程内容一、消息队列&#xff08;了解&#xff09;**为什么消息队列就像是“数据的快递员”&#xff1f;****实际意义**1、产生背景2、消息队列介绍2.1 常见的消息队列产品2.2 应用场景2.3 消息队列中两种消息模型 二、Kafka的基本介绍1、…

Vue3组件设计模式:高可复用性组件开发实战

Vue3组件设计模式:高可复用性组件开发实战 一、前言 在Vue3中&#xff0c;组件设计和开发是非常重要的&#xff0c;它直接影响到应用的可维护性和可复用性。本文将介绍如何利用Vue3组件设计模式来开发高可复用性的组件&#xff0c;让你的组件更加灵活和易于维护。 二、单一职责…

《使用人工智能心脏磁共振成像筛查和诊断心血管疾病》论文精读

Screening and diagnosis of cardiovascular disease using artificial intelligence-enabled cardiac magnetic resonance imaging 心脏磁共振成像 (CMR) 是心脏功能评估的黄金标准&#xff0c;在诊断心血管疾病 (CVD) 中起着至关重要的作用。然而&#xff0c;由于 CMR 解释的…

幂次进近

数学题。 令n-m^k的绝对值最小&#xff0c;即n-m^k0&#xff0c;此时mn^(1/k)。 据题意要求&#xff0c;m只能取到正整数&#xff0c;那么&#xff0c;n^(1/k)结果恰为整时&#xff0c;其值即为答案&#xff0c;否则&#xff0c;答案为该值临近的两个整数中的一个&#xff0c…

RuoYi-Vue-Plus 加入 GitCode:驱动多租户后台管理创新发展

在当今数字化进程持续推进的时代背景下&#xff0c;企业对后台管理系统的要求不断攀升&#xff0c;高效、安全、灵活与可拓展性成为关键要素。近日&#xff0c;RuoYi-Vue-Plus 正式加入 GitCode&#xff0c;为多租户后台管理领域带来全新动力与机遇&#xff0c;有力推动行业技术…

STM32入门教程-示例程序(按键控制LED光敏传感器控制蜂鸣器)

1. LED Blink&#xff08;闪烁&#xff09; 代码主体包含&#xff1a;LED.c key.c main.c delay.c&#xff08;延时防按键抖动&#xff09; 程序代码如下&#xff08;涉及RCC与GPIO两个外设&#xff09;&#xff1a; 1.使用RCC使能GPIO时钟 RCC_APB2PeriphClockC…

数据挖掘实训:天气数据分析与机器学习模型构建

随着气候变化对各行各业的影响日益加剧&#xff0c;精准的天气预测已经变得尤为重要。降雨预测在日常生活中尤其关键&#xff0c;例如农业、交通和灾害预警等领域。本文将通过机器学习方法&#xff0c;利用历史天气数据预测明天是否会下雨&#xff0c;具体内容包括数据预处理、…

Python在Excel工作表中创建数据透视表

在数据处理和分析工作中&#xff0c;Excel作为一个广泛使用的工具&#xff0c;提供了强大的功能来管理和解析数据。当面对大量复杂的数据集时&#xff0c;为了更高效地总结、分析和展示数据&#xff0c;创建数据透视表成为一种不可或缺的方法。通过使用Python这样的编程语言与E…

SpringBoot配置文件

大家好&#xff0c;我是小帅今天我来学习Web开发中的配置文件。 文章目录 1. 配置⽂件作⽤2. 配置⽂件入门3. 配置⽂件的格式4. properties 配置⽂件说明4.1 properties 基本语法4.2 读取配置⽂件&#xff08;Value 注解&#xff09;4.3 properties 缺点分析 5. yml 配置⽂件说…

FPGA的 基本结构(Xilinx 公司Virtex-II 系列FPGA )

以Xilinx 公司Virtex-II 系列FPGA 为例&#xff0c;其基本结构由下图所示。它是主要由两大部分组成&#xff1a;可编程输入/输出&#xff08;Programmable I/Os&#xff09;部分和内部可配置&#xff08;Configurable Logic&#xff09;部分。 可编程输入/输出&#xff08;I/Os…