Flutter集成个推推送-安卓原生篇

news2024/12/28 20:58:52

请添加图片描述

前言

在众多的集成化推送中选择了个推,个推在flutter集成中还是比较简单的,只需要跟着官网一步一步走就可以了。今天这篇文章不涉及到flutter项目个推的集成,只是记录个推离线走安卓厂商时,进行获取一个离线的点击通知数据。

在个推的官网中提供的例子是java的,不符合我的意向,再加上flutter默认是kotlin的,所以本篇文章也是以kotlin的代码为主。

准备工作

项目以集成个推推送并配置好了个推的appId和各方厂商的appIdappKey等。

在服务端的推送代码配置中需要添加push_channel键值对,可以参考下面的代码。

{
    "push_channel":{
        "android":{
            "ups":{
                "notification":{
                    "title":"标题",
                    "body":"内容",
                    "click_type":"intent",
                    "url": "", // 不填
                    "intent": ""
                }
            }
        }
    }
}

原生配置说明

intent 已下面这种为参考进行配置。

  • host: host。这个是自定义的想咋写就咋写。
  • scheme: 协议方案。这个是自定义的想咋写就咋写。
  • package: app 包名。
  • component: 是一个启动的 Activity。
  • payload: 自定义传递的参数。

intent://host?#Intent;scheme=scheme;launchFlags=0x4000000;package=package;component=component;S.payload=payload;S.gttask=;end

配置好的样子大概就是下面这个样子:

intent://host?#Intent;scheme=scheme;launchFlags=0x4000000;package=package;component=包名/包名.MainActivity;S.payload=payload;S.gttask=;end

我们需要在android/app/src/main/AndroidManifest.xmlactivity中找到你配置个推的那块添加下面这样一段代码:

  • host: 这里的host就是上文中配置的host
  • path: 这个可以随便写,根据自己需求来。
  • scheme: 也是上文中的scheme
<data android:host="host" android:path="path" android:scheme="scheme" />

大概就是下面这个样子的:

<activity
    android:name=".MainActivity"
    android:exported="true"
    android:launchMode="singleTop"
    ...
    >
    ...
    
    
    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

            <!-- 自定义的 -->
            <data android:host="host" android:path="path" android:scheme="scheme" />
    </intent-filter>
    
    ...
</activity>

上面这样就已经配置好了,现在开始来写代码。

上路

打开项目的android/app/src/main/kotlin/com/xx/xx/MainActivity.kt文件,引入下面的依赖。

import android.content.Intent 
import android.os.Bundle
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodCall
import io.flutter.embedding.engine.FlutterEngine

然后在MainActivity类中申明通道名称和payload。

// 通道名称
protected var channel: String = "通道名称";

// 获取推送,发给flutter
protected var payLoad: String? = null;

编写原生kotlin代码

我们需要重写onCreateonNewIntentconfigureFlutterEngine这三个方法,我们自己进行重新就可以了,在创建的项目代码中是没有这三个方法的。

一、onCreate

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // 获取自定义透传参数值
    val intent: Intent? = getIntent()
    if (null != intent) {
        payLoad = intent.getStringExtra("payload")
    }
}

二、onNewIntent

override fun onNewIntent(intent: Intent) {
    super.onNewIntent(intent)

    // 获取自定义透传参数值
    if (null != intent) {
        payLoad = intent.getStringExtra("payload")
    }
}

三、configureFlutterEngine

这里我们设置一个名为getIntentData的方法名,并进行判断是否是传递的这个方法名,并进行相关处理。我们后面获取数据全靠它。

override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)

    payLoad = intent.getStringExtra("payload");

    try {

        // 通过MethodChannel调用通知flutter开启参数
        MethodChannel(
                flutterEngine.dartExecutor.binaryMessenger,
                channel
        ).setMethodCallHandler { call: MethodCall, result: MethodChannel.Result -> 
            if (call.method == "getIntentData") {
                result.success("$payLoad")
            } 
        }

    } catch (err: Exception) {}

}

编写dart代码

现在我们回到flutter层面,开始写dart的代码,并进行与我们写的通道进行通信。

申明一个getIntentFuture的异步函数,并创建通道。这里的通道名称一定要和上面我们写的原生通道名称一致,不然没法调用通信。

getIntent() async {
    // 设置通道名称
    const MethodChannel channel = MethodChannel("通道名称");
}

通过invokeMethod的形式去调用我们在原生方面外露的方法名。

String result = await channel.invokeMethod("getIntentData");

接下来判断result是否是正确的值,因为我这边在原生那边通信的时候是将它转成了一个字符串,所以我们判断的是否要以字符串的形式去判断。像下面这样。

if (['null'].contains(result)){}

当我们拿到合规正确的值过后就可以全程在flutter层面进行调用使用了。由于他是一个字符串,我需要将他转成Map的形式来方便使用。

try {
    Map data = json.decode(result);
} catch (error) {
    throw Exception('from-> $result to Map fail, incorrect format');
}

注意

我这里在服务端传递payload的数据时是一个被json化了的字符串,如果朋友你不是这种的字符串记得加处理哦。

如果不知道什么是被json化了的字符串,可以看下面这个:

“{a: 1}”

这个我们就写完啦。这个不能边跑边调试,需要每次以离线跑进行调试,还是稍微有点麻烦。只能以冷启动进行调试。

完整代码

原生代码:

package 包名

import io.flutter.embedding.android.FlutterActivity

import android.content.Intent 
import android.os.Bundle
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodCall
import io.flutter.embedding.engine.FlutterEngine

class MainActivity: FlutterActivity() {

    // 通道名称
    protected var channel: String = "通道名称";
    
    // 获取推送,发给flutter
    protected var payLoad: String? = null;

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // 获取自定义透传参数值
        val intent: Intent? = getIntent()
        if (null != intent) {
            payLoad = intent.getStringExtra("payload")
        }
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)

        // 获取自定义透传参数值
        if (null != intent) {
            payLoad = intent.getStringExtra("payload")
        }
    }

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        payLoad = intent.getStringExtra("payload");

        try {

            // 通过MethodChannel调用通知flutter开启参数
            MethodChannel(
                    flutterEngine.dartExecutor.binaryMessenger,
                    channel
            ).setMethodCallHandler { call: MethodCall, result: MethodChannel.Result -> 
                if (call.method == "getIntentData") {
                    result.success("$payLoad")
                } 
            }

        } catch (err: Exception) {}
    }


}

flutter代码:

Future<Map<String, dynamic>> getIntent() async {
    // 设置通道名称
    const MethodChannel channel = MethodChannel("通道名称");
    
    String result = await channel.invokeMethod("getIntentData");
    Map<String, dynamic> resultData = {};

    if (['null'].contains(result)){
        return resultData;
    }

    try {
        Map data = json.decode(result);
        resultData = data as Map<String, dynamic>;
    } catch (error) {
        throw Exception('from-> $result to Map fail, incorrect format');
    }
    
    return resultData;        
}

最后

以上就是本篇文章的全部内容,希望对此时此刻的你有所帮助。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ChatGPT APIs for HCL DOMINO

大家好&#xff0c;才是真的好。 近期网络上最热闹的话题就是OpenAI的ChatGPT&#xff0c;从去年11月份到现在&#xff0c;一波又一波热潮蜂拥而至&#xff0c;以至于让我们Domino人应接不暇。 ChatGPT和Domino的缘分还真不是完全没有&#xff0c;毕竟刚出来时&#xff0c;很…

Redis(09)centos8下载安装最新redis

redis下载安装 1. 安装make构建工具2. 下载Redis源码包3. 解压源码包并编译4. 配置环境变量5. 注册系统服务6. 设置可远程访问7.防火墙配置: 1. 安装make构建工具 Redis是采用C语言开发的需要编译安装。make是一种自动化编译工具,可以自动编译Redis源代码。 yum install make…

40岁高中老师开源的数据集LAION,改变了生成式AI的未来丨智源大会嘉宾风采

导读 如今&#xff0c;拥有超过50亿个图文对的 LAION数据集已经成为生成式AI未来的中心ーー而随之而来的关于如何监管人工智能的争论也日益激烈。 在德国北部城市汉堡郊区的一栋房屋前&#xff0c;一个信箱上用铅笔潦草地写着一个单词——“ LAION”。这唯一的记号表明&#xf…

jupyter notebook 打开指定文件路径

1 按住winR键&#xff0c;开打运行界面 winR 2 在运行界面输入cmd,进入控制命令行窗口 cmd 4 激活conda环境 conda activate 5 输入要打开的指定路径 #c:\Users\test为要打开的指定路径&#xff0c;用户按需修改即可jupyter notebook c:\Users\test 正常来说&#xff0c;输…

服务注册于发现-Consul

Consul是HashiCorp公司推出的开源工具&#xff0c;用于实现分布式系统的服务发现与配置。 Consul是分布式的、高可用的、可横向扩展的。它具备以下特性 : 服务发现&#xff1a;consul通过DNS或者HTTP接口使服务注册和服务发现变的很容易&#xff0c;一些外部服务&#xff0c;例…

佳能驱动支持,佳能打印机驱动无法安装的解决方法

随着打印机设备的普及&#xff0c;不少用户都会选购一台佳能、惠普、爱普生、兄弟等品牌的打印机&#xff0c;虽然安装打印机及打印机驱动并不难&#xff0c;但也会出现无法安装的情况&#xff0c;只有打印机驱动安装好了才能正常使用佳能打印机设备。以佳能打印机为例&#xf…

关于Vue3刷新页面报错404的解决方法

最近正在写VUE3项目时&#xff0c;遇到了一个问题&#xff0c;页面一刷新就出错。 如下&#xff1a; 查看控制台报错信息是404。 这时候怎么刷新页面都没有用&#xff0c;只能重新输入地址&#xff0c;一想到每次代码发生改变我都要输入一遍地址&#xff0c;那心情都不好了。在…

MongoDB管理神器来袭!NexNoSqlClient让你的效率翻倍!

背景&#xff1a; 如果你在日常工作中需要经常使用MongoDB&#xff0c;那么你一定体验过这样一些痛点;繁琐的脚本编写&#xff0c;冗长的命令行操作&#xff0c;复杂的数据建模和索引等等。这些问题不仅让我们的工作效率低下&#xff0c;还容易出现错误和漏洞&#xff0c;给数…

JavaWeb搭建| Tomcat配置| Maven依赖|这一篇就够了(超详细)

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;老茶icon &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开兴好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;计…

此主机支持 AMD-V,但 AMD-V 处于禁用状态

此主机支持 AMD-V&#xff0c;但 AMD-V 处于禁用状态问题解决 文章目录 此主机支持 AMD-V&#xff0c;但 AMD-V 处于禁用状态问题解决1、问题原因2、题解决办法 1、问题原因 我win 10 系统电脑安装VMware虚拟机后&#xff0c;在启动虚拟机时提示以下这个错误&#xff1a; 此主…

54页数据中台解决方案(ppt可编辑)

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除。 1.3 数据中台是一套解决方案 数据中台是一套可持续“让企业数据用起来”的机制&#xff0c;是一套解决方案&#xff0c;不仅是一个平台。让数据更加灵活地支撑前端业务&…

基于单片机的恒温箱系统设计

以前课设做的小温度传感系统&#xff0c;分享一下&#xff01; 想要直接用的可以去我资源界面下载&#xff0c;传送门。   老规矩先上效果 本系统以AT89C52、DS18B20温度传感器、DS1302实时时钟、LCD1602液晶显示屏模块、蜂鸣器、固态继电器模块等元件构成一个自动恒温加热装…

windows下Qt程序打包简易流程

还记得刚工作那会儿在接触qt不久后想让编译出来的exe文件能够脱离环境运行&#xff0c;比如写个小软件能让其在其他人电脑上动起来&#xff0c;满足一下小小的虚荣心。当时好像挺麻烦的&#xff08;或许当时自己还是了解的太少&#xff09;&#xff0c;有个同事告诉了我一个办法…

NUMA详解

目录 NUMA简介 NUMA开启与关闭 查看系统是否支持 关闭方法 numactl --hardware介绍 没有安装numactl工具下查看NUMA架构节点数&#xff1a; 查看每个NUMA节点的CPU使用情况&#xff1a; 看每个NUMA节点的内存使用情况&#xff1a; 查看NUMA下指定进程的运行情况 创建…

企业如何选择一款适合自己的信息化管理系统?

信息化这个词近年来已经说“烂”了&#xff0c;在这个信息化快速发展的时代&#xff0c;企业信息化管理系统已经成为了企业发展的必要条件之一。 但是&#xff0c;随着市场上信息化产品的爆发式增长&#xff0c;企业在选择适合自己的信息化管理系统时&#xff0c;常常会感到眼…

博弈论又称对策论的入门及在军事博弈问题上的简单实战

学习知识要实时简单回顾&#xff0c;我把学习的博弈论简单梳理一下&#xff0c;方便入门与复习。 博弈论模型 博弈论简介 社会及经济的发展带来了人与人之间或团体之间的竞争及矛盾&#xff0c;应用科学的方法来解决这样的问题开始于 17 世纪的科学家&#xff0c;如 C.&#…

Etcd 可视化管理工具,GUI 客户端

Etcd Assistant——Etcd 可视化管理工具&#xff0c;GUI 客户端 下载地址&#xff1a;http://www.redisant.cn/etcd 主要功能&#xff1a; 支持多标签页&#xff0c;同时连接到多个集群以漂亮的格式显示JSON、XML、MessagePack、十六进制等数据格式浏览、创建、编辑、删除键…

blender的一些使用

导入一个glb文件 可能整体是一个模型 我是看视频 看到可以建筑模型分成了两部分&#xff08;顶面和侧面&#xff09; 然后就一直尝试 首先需要学会的是如何在blender 中修改材质 先按tab 进入编辑模式 选第三个面选择 然后选择一个面以后 选择材质 那个圆的 然后加号 新建…

IEEE旗下SCI审稿流程及状态详细解读 (附科协高质量IEEE期刊目录)~

能够成功发表一篇IEEE旗下SCI论文 (尤其是TRANS系列) 是很多电气电子工程、计算机及通信领域科研工作者的梦想。很多学者初次投稿IEEE后&#xff0c;会不停登录投稿系统查看状态&#xff0c;其实不必如此心急&#xff0c;只需掌握几个重要的时间节点&#xff0c;定期登录系统查…

想提高应用程序的用户满意度——APK体积包优化少不了

作者&#xff1a;子不语Any 前言 减少应用程序安装包的大小&#xff0c;不仅仅减少用户的网络数据流量&#xff0c;还减少了下载等待的时间。毋庸置疑&#xff0c;尽量减少程序安装包的大小是十分有必要的。 通常来说&#xff0c;减少程序安装包的大小有两条规律&#xff1a;…