flutter 使用wechatkit 进行分享 获取extinfo

首先有两个库

wechat_kit 基本分享 小程序分享等

wechat_kit | Flutter PackageA powerful Flutter plugin allowing developers to auth/share/pay with natvie Android & iOS Wechat SDKs.icon-default.png?t=N7T8https://pub-web.flutter-io.cn/packages/wechat_kit需要调用微信sdk的api 还有使用下面的库

wechat_kit_extension | Dart PackageAn extension package for wechat_kit, including WeChat API integrations.icon-default.png?t=N7T8https://pub-web.flutter-io.cn/packages/wechat_kit_extension

一、基本分享功能、

yaml 配置wechat_kit 

dependencies:
  wechat_kit: ^${latestTag}
#  wechat_kit:
#    git:
#      url: https://github.com/RxReader/wechat_kit.git

wechat_kit:
#  ios: no_pay # 默认 pay
  app_id: ${your wechat app id}
  universal_link: https://${your applinks domain}/universal_link/${example_app}/wechat/

进行封装

自己根据实际情况 进行下面的配置

  static const String kAppId = '';
  static const String kUniversalLink =
      '';
  static const String kAppSecret = '';

  static const String kMini = '';

  static const String weixiCustomerService =
      '';
  static const String corpId = '';

 封装代码

class WeChatConfig {
  static const String kAppId = '';
  static const String kUniversalLink =
      '';
  static const String kAppSecret = '';

  static const String kMini = '';

  static const String weixiCustomerService =
      '';
  static const String corpId = '';

  static register() {
    WechatKitPlatform.instance.registerApp(
      appId: kAppId,
      universalLink: kUniversalLink,
    );
    WechatKitPlatform.instance.reqStream().listen((event) {
      final info = event.toJson();
      // print("[WeChat] $info");
      if (info["messageExt"] != null && info["messageExt"] != "") {
        Get.to(() => ArticleDes(
              communityArticlesData: ValueNotifier(
                CommunityArticlesData(
                  id: info["messageExt"],
                ),
              ),
            ));
      }
    });
  }

  static Future login() {
    return WechatKitPlatform.instance.auth(
      scope: <String>[WechatScope.kSNSApiUserInfo],
      state: 'auth',
    );
  }

  static Future launchMiniProgram(String path) {
    String dev_path;
    if (release) {
      dev_path = '$path&environment=pro';
    } else {
      dev_path = '$path&environment=test';
    }
    return WechatKitPlatform.instance.launchMiniProgram(
        userName: kMini,
        path: dev_path,
        type:
            release ? WechatMiniProgram.kRelease : WechatMiniProgram.kPreview);
  }

  static Future shareMiniProgram(
      String title, String path, String webpageUrl, Uint8List uint8list) async {
    if (!await WechatKitPlatform.instance.isInstalled()) {
      if (Platform.isIOS) {
        await launchUrl(Uri.parse(Config.wxIosInstallAddress));
      } else {
        await launchUrl(Uri.parse(Config.wxAndroidInstallAddress));
      }
      return;
    }
    return WechatKitPlatform.instance
        .shareMiniProgram(
            scene: WechatScene.kSession,
            title: title,
            path: path,
            webpageUrl: webpageUrl,
            hdImageData: uint8list,
            type: release
                ? WechatMiniProgram.kRelease
                : WechatMiniProgram.kPreview,
            userName: kMini)
        .catchError((e) {
      Get.log('===$e');
    });
  }

  static Future shareLinkToWeChat({
    String? title,
    String? description,
    required String webpageUrl,
    Uint8List? uint8list,
  }) async {
    if (!await WechatKitPlatform.instance.isInstalled()) {
      if (Platform.isIOS) {
        await launchUrl(Uri.parse(Config.wxIosInstallAddress));
      } else {
        await launchUrl(Uri.parse(Config.wxAndroidInstallAddress));
      }
      return;
    }
    try {
      await WechatKitPlatform.instance.shareWebpage(
        title: title,
        description: description,
        scene: WechatScene.kSession,
        webpageUrl: webpageUrl,
        thumbData: uint8list,
      );
    } catch (e) {
      // Handle any potential errors
    }
  }

  static Future shareImg(
      {String? title,
      String? description,
      Uint8List? imageData,
      Uint8List? thumbData,
      Uri? imageUri}) async {
    if (!await WechatKitPlatform.instance.isInstalled()) {
      if (Platform.isIOS) {
        await launchUrl(Uri.parse(Config.wxIosInstallAddress));
      } else {
        await launchUrl(Uri.parse(Config.wxAndroidInstallAddress));
      }
      return;
    }
    return WechatKitPlatform.instance
        .shareImage(
            scene: WechatScene.kSession,
            title: 'app',
            description: description,
            imageData: imageData,
            thumbData: thumbData,
            imageUri: imageUri)
        .catchError((e) {
      Get.log('===$e');
    });
  }

  static Future openCustomerServiceChat() {
    return WechatKitPlatform.instance
        .openCustomerServiceChat(corpId: corpId, url: weixiCustomerService);
  }

  //通过ImageProvider读取Image
  static Future<ui.Image> loadImageByProvider(
    ImageProvider provider, {
    ImageConfiguration config = ImageConfiguration.empty,
  }) async {
    Completer<ui.Image> completer = Completer<ui.Image>(); //完成的回调
    late ImageStreamListener listener;
    ImageStream stream = provider.resolve(config); //获取图片流
    listener = ImageStreamListener((ImageInfo frame, bool sync) {
      //监听
      final ui.Image image = frame.image;
      completer.complete(image); //完成
      stream.removeListener(listener); //移除监听
    });
    stream.addListener(listener); //添加监听
    return completer.future; //返回
  }

  //通过[Uint8List]获取图片,默认宽高[width][height]
  static Future<ui.Image> loadImageByUint8List(
    Uint8List list, {
    required int width,
    required int height,
  }) async {
    ui.Codec codec = await ui.instantiateImageCodec(list,
        targetWidth: width, targetHeight: height);
    ui.FrameInfo frame = await codec.getNextFrame();
    return frame.image;
  }

  static Future<String> saveImage(Uint8List imageBytes) async {
    final directory = await getApplicationDocumentsDirectory();

    final String path =
        '${directory.path}/image_${DateTime.now().millisecondsSinceEpoch}.png';
    final file = File(path);
    await file.writeAsBytes(imageBytes);
    return path;
  }

  static Future<Uint8List> widgetToImage(GlobalKey _globalKey,
      {double pixelRatio = 1}) async {
    Completer<Uint8List> completer = Completer();

    RenderRepaintBoundary render =
        _globalKey.currentContext!.findRenderObject() as RenderRepaintBoundary;

    ui.Image image = await render.toImage(pixelRatio: pixelRatio);

    ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    completer.complete(byteData?.buffer.asUint8List());

    return completer.future;
  }

  ///图片压缩
  static Future<Uint8List> compressAsset(Uint8List u, int w, int h) async {
    if (u.buffer.lengthInBytes > (128 * 1024)) {
      print("===开始压缩图片${u.buffer.lengthInBytes ~/ 1024}");
      var list = await FlutterImageCompress.compressWithList(u,
          minHeight: w, minWidth: h, quality: 95, format: CompressFormat.jpeg);
      print("===压缩过后图片${list.buffer.lengthInBytes ~/ 1024}");
      if (list.buffer.lengthInBytes > (128 * 1024)) {
        print("===继续压缩图片大小");
        list = await compressAsset(list, w, h);
      }
      return list;
    } else {
      return u;
    }
  }

  ///widget转图片 如果大于128kb 进行压缩
  static Future<Uint8List> widgetToMiniImage(GlobalKey _globalKey,
      {double pixelRatio = 1}) async {
    Completer<Uint8List> completer = Completer();
    Get.log('=_globalKey=${_globalKey.currentContext?.width}');
    Get.log('=_globalKey=${_globalKey.currentContext?.height}');

    RenderRepaintBoundary render =
        _globalKey.currentContext!.findRenderObject() as RenderRepaintBoundary;

    ui.Image image = await render.toImage(pixelRatio: 3);

    double scale = calcScale(
        srcWidth: image.width.toDouble(), srcHeight: image.height.toDouble());
    Get.log('=$scale image=${image.width}');
    Get.log('=image=${image.height}');
    ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    ui.Codec codec = await ui.instantiateImageCodec(
        byteData!.buffer.asUint8List(),
        targetWidth: 500,
        targetHeight: 400);
    ui.FrameInfo frame = await codec.getNextFrame();
    Get.log('=frame=${frame.image.width}');
    Get.log('=frame=${frame.image.height}');
    byteData = await frame.image.toByteData(format: ui.ImageByteFormat.png);
    Uint8List u = await compressAsset(byteData!.buffer.asUint8List(),
        image.width ~/ scale, image.height ~/ scale);
    Get.log('=len=${(u.buffer.lengthInBytes) / 1024}');
    completer.complete(u);

    return completer.future;
  }

  static double calcScale({
    required double srcWidth,
    required double srcHeight,
  }) {
    var scaleW = srcWidth / 500;
    var scaleH = srcHeight / 400;
    var scale = math.max(1.0, math.min(scaleW, scaleH));
    return scale;
  }

  static Future<Uint8List> imGToMiniImage(ui.Image img,
      {double pixelRatio = 1}) async {
    Completer<Uint8List> completer = Completer();

    ui.Image image = img;

    ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    ui.Codec codec = await ui.instantiateImageCodec(
        byteData!.buffer.asUint8List(),
        targetWidth: 300,
        targetHeight: 230);
    ui.FrameInfo frame = await codec.getNextFrame();
    Get.log('=frame=${frame.image.width}');
    Get.log('=frame=${frame.image.height}');
    byteData = await frame.image.toByteData(format: ui.ImageByteFormat.png);
    if ((byteData?.buffer.lengthInBytes ?? 0) >= 131072) {}
    completer.complete(byteData?.buffer.asUint8List());

    return completer.future;
  }
}

 h5打开app通过 wx-open-launch-app 标签进行打开 携带参数extinfo app端接收

App获取开放标签\中的extinfo数据 | 微信开放文档

接收逻辑如下

    WechatKitPlatform.instance.reqStream().listen((event) {
      final info = event.toJson();
      // print("[WeChat] $info");
      if (info["messageExt"] != null && info["messageExt"] != "") {
        // 做跳转等操作
      }
    });

判断是否下载微信,进行不同平台微信下载

 static const wxIosInstallAddress =
      "https://apps.apple.com/cn/app/wechat/id414478124";

  static const wxAndroidInstallAddress = "https://weixin.qq.com/";
  if (!await WechatKitPlatform.instance.isInstalled()) {
      if (Platform.isIOS) {
        await launchUrl(Uri.parse(Config.wxIosInstallAddress));
      } else {
        await launchUrl(Uri.parse(Config.wxAndroidInstallAddress));
      }
      return;
    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[leetcode] 47. 全排列 II

文章目录 题目描述解题方法dfsjava代码复杂度分析 相似题目 题目描述 给定一个可包含重复数字的序列 nums &#xff0c;按任意顺序 返回所有不重复的全排列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,2] 输出&#xff1a; [[1,1,2],[1,2,1],[2,1,1]]示例 2&#xff…

软件测试面试在简历上写了“精通”后,拥有工作经验的我被面试官问到窒息...

前言 如果有真才实学&#xff0c;写个精通可以让面试官眼前一亮&#xff01; 如果是瞎写&#xff1f;基本就要被狠狠地虐一把里&#xff01; 最近在面试&#xff0c;我现在十分后悔在简历上写了“精通”二字… 先给大家看看我简历上的技能列表&#xff1a; 熟悉软件测试理…

T2最长的AB序列(20分) - 京东前端笔试编程题题解

考试平台&#xff1a; 牛客网 题目类型&#xff1a; 选择题&#xff08;40分&#xff09; 3道编程题&#xff08;60分&#xff09; 考试时间&#xff1a; 2024-03-23 &#xff08;两小时&#xff09; 题目描述 给出一个仅由字符AB构成的字符串Str 请你求出S中包含A和B个数相…

解码视频流在opengl中的贴图投影计算

解码视频流在opengl中的贴图投影计算 修改顶点着色器cpp 文件放大缩小 我们把视频当成纹理,首先要确定贴入的坐标&#xff0c;原始坐标如下所示 static float vertices[] {// ---- 位置 ---- ---- 颜色 ---- - 纹理坐标 -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f…

【Gitea的介绍】

&#x1f525;博主&#xff1a;程序员不想YY啊&#x1f525; &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家&#x1f4ab; &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 &#x1f308;希望本文对您有所裨益&#xff0c;如有…

火鸟门户系统—旅游度假模块

旅游度假 简介 旅游度假功能为用户提供一站式旅游度假服务&#xff0c;车站、酒店民宿、门票、跟团游、货运、签证等多个方面&#xff0c;满足用户多样化的旅游需求。 功能 订单&#xff1a;提供订单预订服务&#xff0c;用户可以根据自身需求选择合适的旅行产品。酒店民宿…

element+Vue2,在一个页面跳转到另一个页面,并自动选中table的某一行

需求&#xff1a;点击A页面的某处&#xff0c;跳转到B页面并选中B页面表格的某一行&#xff08;点击B页面的搜索后需要清空默认选择的状态&#xff09;环境&#xff1a;vue2、element的table&#xff0c;table允许多选知识点&#xff1a;主要使用到table的这两属性&#xff1a;…

MySQL 全景图

前言 MySQL是啥&#xff1f;我一直以为MySQL是数据库&#xff0c;直到我最近看了很多关于MySQL的文章、专栏以及书籍后&#xff0c;我对MySQL的才有了更加深刻的体会。 原来MySQL并不是数据库&#xff0c;又或者说&#xff0c;我认为“MySQL是数据库这种想法”是片面的。其实…

SpringBoot 集成分布式任务调度 XXL-JOB【保姆级上手】

文章目录 XXL-JOB 介绍分布式任务调度XXL-JOB 概述 快速入门下载源码初始化调度数据库编译源码调度中心调度中心介绍配置调度中心部署调度中心集群部署调度中心&#xff08;可选&#xff09;Docker 镜像方式搭建调度中心&#xff08;可选&#xff09; 执行器执行器介绍添加依赖…

Talend API Tester-api接口测试插件

这是Google的一个扩展&#xff0c;直接在右上角&#xff0c;扩展程序——管理扩展程序直接下载安装就可以了 web接口测试是非常方便的

若依框架学习使用

若依官网项目拉取下来介绍 | RuoYi 项目运行&#xff1a; 1.idea安装&#xff0c;可以运行前后端 编辑器idea、jdk环境安装、数据库mysql、navicat工具、redis(redis-server启动)安装 2.navicat数据库连接, 创建数据库ry-vue并导入数据脚本ry_2021xxxx.sql&#xff0c;qua…

国内ip怎么来回切换:操作指南与注意事项

在数字化时代&#xff0c;互联网已经成为我们日常生活、学习和工作中不可或缺的一部分。然而&#xff0c;随着网络应用的不断深化&#xff0c;用户对于网络环境的稳定性和安全性要求也越来越高。其中&#xff0c;IP地址作为网络中的关键标识&#xff0c;其切换与管理显得尤为重…

基于jsp+Spring boot+mybatis的图书管理系统设计和实现

基于jspSpring bootmybatis的图书管理系统设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获…

基于 google 的 libphonenumber 将手机号转成地区及供应商信息

依赖&#xff1a; <dependency><groupId>com.googlecode.libphonenumber</groupId><artifactId>libphonenumber</artifactId><version>8.13.26</version> </dependency> <dependency><groupId>com.googlecode.lib…

CVE-2022-29405 Apache Archiva任意用户密码重置漏洞分析

Apache Archiva是一套可扩展的Artifact Repository管理系统。它能够与Maven&#xff0c;Continuum和ANT等构建工具完美结合。Archiva提供的功能包括&#xff1a;远程Repository代理&#xff0c;基于角色的安全访问管理&#xff0c;Artifact分发、维护、查询&#xff0c;生成使用…

强烈推荐:2024 年12款 Visual Studio 亲测、好用、优秀的工具,AI插件等

工具类扩展 1. ILSpy 2022 &#xff08;免费&#xff09; ILSpy 是 ILSpy 开源反编译器的 Visual Studio 扩展。 是一款开源、免费的、且适用于.NET平台反编译【C#语言编写的程序和库(.dll)内容】工具&#xff1b;可以集成在Visual Studio 开发工具中&#xff0c;能够十分快捷…

探索父进程和子进程

文章目录 通过系统调用查看进程PID父进程、子进程 通过系统调用创建进程-fork初识为什么fork给父进程返回子进程的PID&#xff0c;给子进程返回0fork函数如何做到返回两个值一个变量为什么同时会有两个返回值&#xff1f;bash总结 通过系统调用查看进程PID getpid()函数可以获…

【面试题】RocketMQ如何处理消息重复的问题呢?

对分布式消息队列来说&#xff0c;同时做到确保一定投递和不重复投递是很难的&#xff0c;就是所谓的“有且仅有一次” 。RocketMQ择了确保一定投递&#xff0c;保证消息不丢失&#xff0c;但有可能造成消息重复。 处理消息重复问题&#xff0c;主要有业务端自己保证&#xff…

【Docker】搭建强大易用的个人博客 - Halo

【Docker】搭建强大易用的个人博客 - Halo 前言 本教程基于绿联的NAS设备DX4600 Pro的docker功能进行搭建&#xff0c;采用Halo MySQL实例作为演示。 简介 Halo [ˈheɪloʊ] 是一个简洁&#xff0c;现代&#xff0c;快速且非常灵活的建站工具&#xff0c;它是由一位中国开…