You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter使用receive_sharing_intent接收分享时无法跳转指定页面

问题原因

你当前的代码存在两个核心问题,对应两个跳转失败场景:

  • 冷启动跳转失败:直接在MyApp的build方法中执行导航逻辑,此时MaterialApp的路由栈还未完成初始化,传入的context不具备导航操作能力,Navigator.push执行无效。
  • 前台运行跳转失败:ReceiveSharingIntent.getInitialMedia()仅会在App进程完全未存活、被分享动作冷启动时返回分享内容,App处于前台/后台存活状态被分享唤起时,分享内容是通过流事件推送的,你当前代码没有监听对应流,自然拿不到回调触发跳转。
修复方案

需要同时覆盖冷启动、App存活唤起两个场景,同时保证跳转时机在路由初始化完成后执行,具体实现步骤:

  1. 定义全局NavigatorKey,绑定到MaterialApp上,避免依赖未初始化的组件context做导航。
  2. 将根组件MyApp改为StatefulWidget,在初始化逻辑中同时处理冷启动的初始分享内容、监听App存活时的分享流事件。
  3. 跳转逻辑放在首帧渲染完成的回调中执行,避免路由未挂载报错。
  4. 页面销毁时取消流订阅,防止内存泄漏。
完整可运行代码
import 'package:flutter/material.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
import 'dart:async';

// 全局导航key,用于获取有效路由上下文
final GlobalKey<NavigatorState> globalNavigatorKey = GlobalKey<NavigatorState>();

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  StreamSubscription? _shareEventListener;

  @override
  void initState() {
    super.initState();
    _initShareListener();
  }

  @override
  void dispose() {
    // 销毁时取消流订阅,避免内存泄漏
    _shareEventListener?.cancel();
    super.dispose();
  }

  /// 统一处理分享跳转逻辑
  void _navigateToAddPage(List<SharedMediaFile> shareFiles) {
    if (shareFiles.isEmpty) return;
    // 等首帧渲染完成、路由栈完全初始化后再跳转
    WidgetsBinding.instance.addPostFrameCallback((_) {
      globalNavigatorKey.currentState?.push(
        MaterialPageRoute(
          builder: (_) => CategoryAddScreen(shareMediaList: shareFiles),
        ),
      );
    });
  }

  /// 初始化两个场景的分享监听
  void _initShareListener() {
    // 处理冷启动场景:App进程未存活时被分享唤起
    ReceiveSharingIntent.getInitialMedia().then(_navigateToAddPage);
    // 处理App存活场景:App在前台/后台运行时被分享唤起
    _shareEventListener = ReceiveSharingIntent.getMediaStream().listen(_navigateToAddPage);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: globalNavigatorKey, // 绑定全局导航key
      // 保留你原有MaterialApp的其他配置,比如主题、首页、路由表等
      // theme: ThemeData(...),
      // home: const HomePage(),
      // ...
    );
  }
}

// 示例目标页面,可根据你的业务调整
class CategoryAddScreen extends StatelessWidget {
  final List<SharedMediaFile> shareMediaList;
  const CategoryAddScreen({Key? key, required this.shareMediaList}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('新增分类')),
      body: Center(child: Text('收到分享文件${shareMediaList.length}个')),
    );
  }
}
注意事项
  • 若修改后仍无法收到回调,优先检查原生端配置:Android需确认AndroidManifest.xml中对应Activity配置了匹配图片分享的intent-filter,iOS需确认Info.plist中配置了正确的分享权限与扩展。
  • 如果需要在跳转前做登录态等前置判断,直接在_navigateToAddPage方法中加判断逻辑即可,满足条件再执行push。
  • 插件默认会缓存上一次的分享内容,如需重置可在处理完分享逻辑后调用ReceiveSharingIntent.reset()清除缓存,避免重复触发跳转。

内容的提问来源于stack exchange,提问作者Too

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 00:12:40