【Flutter 专题】120 Flutter 腾讯移动通讯 TPNS~

1.2 方法使用

小菜按照官网的介绍尝试了一些常用的 API 方式,主要分为应用类,账号类和标签类三种 API,小菜业务中没有应用账号和标签模块,暂未深入研究;

  • 应用接口 API
a. 注册推送服务

对于服务的注册初始化,可以在首次进入应用 initState() 中直接初始化,也可以根据业务逻辑在固定的位置进行初始化,需要传递申请的账号 IDKEY;注册成功之后会在 onRegisteredDone() 中进行回调,并获取对应设备的唯一 Token

XgFlutterPlugin().startXg(“1500018481”, “AW8Y2K3KXZ38”);

// 注册回调
XgFlutterPlugin().addEventHandler(
onRegisteredDone: (String msg) async {
print(“HomePage -> onRegisteredDone -> $msg”);
_showDialog(‘注册成功’, msg);
},
);

b. 注销推送服务

服务的注销方法可以通过 stopXg() 进行处理,并在 unRegistered 进行回调监听;

XgFlutterPlugin().stopXg();

// 注销回调
XgFlutterPlugin().addEventHandler(
unRegistered: (String msg) async {
print(“HomePage -> unRegistered -> $msg”);
},
);

c. 设备推送标识

对于设备唯一标识的获取,可以通过注册初始化成功之后获取,也可以通过 XgFlutterPlugin.xgToken 获取唯一 Token

Future getTPNSToken(title) async {
try {
String xgToken = await XgFlutterPlugin.xgToken;
print(‘HomePage -> getTPNSToken -> $xgToken’);
_showDialog(title, xgToken);
} catch (e) {
print(e.toString());
}
}

d. 上报角标数

对于桌面角标,在通知类消息中 华为小米 设备在开启权限之后,接收通知会由桌面角标的更新;而 TPNS 提供的 setBadge() 只有在 iOS 环境下支持,对于 Android 环境下的透传类型或其他厂商设备的支持,可以通过 FlutterNative 通信来由原生实现;

e. SDK 版本

TPNS SDK 版本可以通过 XgFlutterPlugin.xgSdkVersion 获取;

Future getTPNSSDKVersion(title) async {
try {
String sdkVersion = await XgFlutterPlugin.xgSdkVersion;
print(‘HomePage -> getTPNSSDKVersion -> $sdkVersion’);
_showDialog(title, sdkVersion);
} catch (e) {
print(e​
.toString());
}
}

  • 账号接口 API

TPNS 提供了个性化服务,关于账号的绑定和解绑等功能,可以根据具体的业务逻辑进行处理;

String inputStr = “ACE_Flutter”;
// 设置账号
XgFlutterPlugin().setAccount(inputStr, AccountType.UNKNOWN);
// 解绑账号
XgFlutterPlugin().deleteAccount(inputStr, AccountType.UNKNOWN);
// 清空账号
XgFlutterPlugin().cleanAccounts();

XgFlutterPlugin().addEventHandler(
xgPushDidBindWithIdentifier: (String msg) async {
print(“HomePage -> xgPushDidBindWithIdentifier -> $msg”);
_showDialog(‘绑定标签 $inputStr’, msg);
},
xgPushDidUnbindWithIdentifier: (String msg) async {
print(“HomePage -> xgPushDidUnbindWithIdentifier -> $msg”);
_showDialog(‘解绑账号’, msg);
},
xgPushDidClearAllIdentifiers: (String msg) async {
print(“HomePage -> xgPushDidClearAllIdentifiers -> $msg”);
_showDialog(‘清除全部账号’, msg);
}
)

  • 标签接口 API

TPNS 的用户标签功能比较强大,可以针对性的进行地理围栏或标签分布的推送;TPNS 提供了绑定和解绑标签,更新和清理标签等功能,方便针对性的进行数据推送;

String inputStr = “ACE_Flutter”;
// 绑定标签
XgFlutterPlugin().addTags([inputStr]);
// 解绑标签
XgFlutterPlugin().deleteTags([inputStr]);
// 更新标签
XgFlutterPlugin().setTags([inputStr]);
// 清除标签
XgFlutterPlugin().cleanTags();

2. 通知类消息

小菜在上一篇文章中介绍了 TPNS 消息发布后台,不管是哪种方式集成,发布后台是一致的;

2.1 接收 & 展示

通知类 Push 在设备开启权限时,接收消息后会自动展示通知,这是由 TPNS SDK 实现好的,与原生一致,通知类 Push 标题和内容也只能以通过消息后台发布为准,不能自由更改;其中 通知类 Push 接收通过 onReceiveNotificationResponse() 方法回调监听;

XgFlutterPlugin().addEventHandler(
onReceiveNotificationResponse: (Map<String, dynamic> msg) async {
print(“HomePage -> onReceiveNotificationResponse -> $msg”);
_showDialog(‘通知类消息接收’, msg.toString());
},
);

TPNS_通知类_接收.jpg TPNS_通知类_展示.jpg

2.2 点击

通知类 Push 消息点击是通过 xgPushClickAction() 方法进行回调,之后的业务逻辑可以根据消息返回的信息进行处理;小菜为了适配其他的 Push 类型,调整了点击后的操作,默认为启动 app,小菜通常在【附加参数】中添加 Json 进行数据解析,在进行之后的业务处理;

XgFlutterPlugin().addEventHandler(
xgPushClickAction: (Map<String, dynamic> msg) async {
print(“HomePage -> xgPushClickAction -> $msg”);
_showDialog(‘通知类消息点击’, msg.toString());
},
);

TPNS_通知类_点击.jpg

3. 透传类消息

透传类 Push 相比 通知类 Push 要复杂一些,TPNS 只提供了 透传类 Push 接收,不会进行 Notification 通知展示;因此小菜通过 Flutter-Native 消息通信进行处理;其中 Notification 的展示点击需要 Native 方面进行配合处理;

3.1 接收

透传类 Push 通过 onReceiveMessage() 进行消息接收的回调监听;之后,小菜建立一个 MethodChannel 将消息传递给 Android Native

XgFlutterPlugin().addEventHandler(
onReceiveMessage: (Map<String, dynamic> msg) async {
print(“HomePage -> onReceiveMessage -> $msg”);
_showDialog(‘透传类消息接收’, msg.toString());
await methodChannel
.invokeMethod(‘tpns_extras’, msg[‘customMessage’])
.then((val) {
print(“HomePage -> 透传类消息接收 -> $val”);
if (val != null) {
_showDialog(‘透传类消息点击’, val);
}
});
},
);

TPNS_透传类_接收.jpg

3.2 展示

Flutter 端在接收到 透传类 Push 消息时,发送 MethodChannelAndroid NativeNative 端在解析对应参数进行 Notification 展示;

@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(),
“com.ace.plugin.flutter_app/tpns_notification”).setMethodCallHandler(new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
if (call != null && call.method.equals(“tpns_extras”)) {
setNotification(MainActivity.this, call.arguments.toString());
mResult = result;
} else {
result.notImplemented();
}
}
});
}

TPNS_透传类_展示.jpg

3.3 点击

Native 端展示 Notification 后,小菜尝试两种方式,第一种是通过一个新的 BasicMessageChannel 来进行消息通信到 Flutter 端,第二种是通过之前 Flutter 发送的 MethodChannel 进行 result 回调;小菜虽然应用了第二种方式,但更倾向于第一种,每个事件更加专一;

Flutter 端接收到 Native 发送或返回的消息后便可自由进行业务逻辑处理了;

private void setNotification(Context context, String extras) {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel =
new NotificationChannel(“ace_push”, “ace_push_name”, NotificationManager.IMPORTANCE_HIGH);
if (notificationManager != null) {
notificationManager.createNotificationChannel(channel);
}
}
int notificationId = new java.util.Random().nextInt(1000);

//Intent intent = new Intent(MainActivity.this, TPNSNotificationReceiver.class);
//PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 101, intent, 102);
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra(“push_extras”, extras);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent =
PendingIntent.getActivity(context, notificationId, intent, PendingIntent.FLAG_CANCEL_CURRENT);
JSONObject json = JSONObject.parseObject(extras);
String extrasStr = json.getString(“extras”);
json = JSONObject.parseObject(extrasStr);
String title = json.getString(“title”);
String desc = json.getString(“desc”);
Notification notification = new NotificationCompat.Builder(context, “ace_push”).setContentTitle(title)
.setContentText(desc)

最后

小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

资料⬅专栏获取
成长,自己不成体系的自学效果低效漫长且无助**。

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

[外链图片转存中…(img-ugKoboG8-1719094803252)]一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

资料⬅专栏获取

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

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

相关文章

【嵌入式Linux】i.MX6ULL 时钟树——理论分析

文章目录 0. 时钟树结构0.1 参考手册 Chapter 18​: Clock Controller Module (CCM)0.2 时钟信号路径 1. 时钟源——晶振1.1 外部低频时钟 - CKIL1.1.1 CKIL 同步到 IPG_CLK 解释 1.2 外部高频时钟 - CKIH 和 内部振荡器1.3 总结1.4 缩写补充 2. PLL时钟2.1 i.MX6U 芯片 PLL 时…

不用写一行代码,deepseek结合腾讯云语音识别来批量转录Mp3音频

首先&#xff0c;打开window系统中的cmd命令行工具&#xff0c;或者powershell&#xff0c;安装腾讯云tencentcloud的Python库 pip install -i https://mirrors.tencent.com/pypi/simple/ --upgrade tencentcloud-sdk-python 然后&#xff0c;开通腾讯云的对象存储COS服务&…

关于DrawTools的分析- 一个优秀的C#开源绘图软件

国外大佬&#xff0c;曾经写过两个关于DrawTools相关的开源绘图软件。 我更新了一个优化的版本如下图&#xff0c;稍后会发布更新给大家。 需要的用户可发邮件给我 448283544qq.com 应用于AGV地图编辑器如下&#xff1a; 那么这个优于很多普通的画布软件&#xff0c;包含点、…

Android进程间通信 Messenger详解

//这里服务端Service是运行在单独的进程中的 android:process“:other” class MessengerService : Service() { private lateinit var mMessenger: Messenger override fun onBind(intent: Intent): IBinder { log(TAG, “onBind~”) //传入Handler实例化Messenger mMes…

Redis数据库的删除和安装

Redis数据库的删除和安装 1、删除Redis数据库2、下载Redis数据库 1、删除Redis数据库 没有下载过的&#xff0c;可以直接跳到下面的安装过程↓ 我们电脑中如果有下载过Redis数据库&#xff0c;要更换版本的话&#xff0c;其实Redis数据库的删除是比较简单的&#xff0c;打开我…

leetcode 二分查找·系统掌握 第一个错误版本

题意&#xff1a; 题解&#xff1a; 就是经典的~01~泛型查找&#xff0c;而且一定存在这样错误的版本所以查找不会"失败"&#xff0c;返回每次查找结果即可。 int firstBadVersion(int n) {long l1,rn,mid;while(l<r){mid(lr)>>1;if(isBadVersion(mid))r…

微积分-导数1(导数与变化率)

切线 要求与曲线 C C C相切于 P ( a , f ( a ) ) P(a, f(a)) P(a,f(a))点的切线&#xff0c;我们可以在曲线上找到与之相近的一点 Q ( x , f ( x ) ) Q(x, f(x)) Q(x,f(x))&#xff0c;然后求出割线 P Q PQ PQ的斜率&#xff1a; m P Q f ( x ) − f ( a ) x − a m_{PQ} \…

csdn上传源码资源卖钱能买房买车吗?每天最高收入200-500?

csdn上传源码卖钱能买房买车吗,最高收入200-500&#xff1f; 作者收入日榜 不***孩 收益617.32元 程***妍 收益534.56元 s***n 收益323.71元 盈***客 收益315.05元 极***计 收益284.17元

[第五空间2019 决赛]PWN5

参考文章: 格式化字符串漏洞原理及其利用&#xff08;附带pwn例题讲解&#xff09;_格式化字符串攻击教程-CSDN博客 格式化字符串漏洞原理详解_静态编译 格式化字符串漏洞-CSDN博客 BUU pwn [第五空间2019 决赛]PWN5 //格式化字符串漏洞 - Nemuzuki - 博客园 (cnblogs.com) …

如果申请小程序地理位置接口权限之前刷到这一篇就好了

小程序地理位置接口有什么功能&#xff1f; 通常情况下&#xff0c;我们在开发小程序时&#xff0c;可能会用到获取用户地理位置信息的功能。小程序开发者开放平台的新规定指出&#xff0c;如果没有申请开通微信小程序地理位置接口&#xff08;getLocation&#xff09;&#xf…

【建议收藏】Android中高级大厂面试源码秘籍,为你备战2021金三银四,直通大厂

首先来说下为什么要读源码&#xff0c;有学习源码的必要吗&#xff1f; 为什么要阅读源码&#xff1f; 关于为什么阅读和学习源码&#xff0c;我个人认为可能有以下几点&#xff1a; &#xff08;一&#xff09;吊打面试官&#xff0c;应对面试 为了找到更好的工作&#xff…

【小沐学AI】Python实现语音识别(Whisper-Web)

文章目录 1、简介2、下载2.1 openai-whisper2.2 whisper-web 结语 1、简介 https://openai.com/index/whisper/ Whisper 是一种自动语音识别 &#xff08;ASR&#xff09; 系统&#xff0c;经过 680,000 小时的多语言和多任务监督数据的训练&#xff0c;从网络上收集。我们表…

Jenkins定时构建自动化(一):Jenkins下载安装配置

目录 ​编辑 一、jdk下载安装 1. 已下载安装jdk 2. 未下载安装jdk 二、jenkins安装 1. .war包安装 三、获取IP地址 四、jenkins网页配置 一、jdk下载安装 1. 已下载安装jdk &#xff08;1&#xff09;查询jdk版本命令&#xff1a;java -version &#xff08;2&#xff09;…

4.XSS-反射型(get)利用:获取cookie

GET反射型XSS利用&#xff1a;获取cookie 修改一下配置文件\pikachu\pkxss\xcookie\cookie.php 我这里将对应的IP地址修改为本地pikachu的主站IP地址&#xff0c;这样给用户造成一种正常视觉上的欺骗&#xff0c;容易上当。重定向到pikachu主页面 基于IP搭建的pkxss平台(入侵…

Python 函数注解,给函数贴上小标签

目录 什么是函数注解? 为什么使用函数注解? 如何编写函数注解? 实战演练 与类型提示(Type Hints)的关系 类型安全的运算器 什么是函数注解? 函数注解(Function Annotations)是Python 3中新增的一个特性,它允许为函数的参数和返回值指定类型。 这些注解不会改变…

高速缓存存储器(Chche)

为了解决CPU和主存之间速度不匹配的问题&#xff0c;计算机系统中引入了高速缓存&#xff08;Chche&#xff09;的概念。 基本想法&#xff1a;使用速度更快但容量更小、价格更高的SRAM制作一个缓冲存储器&#xff0c;用来存放经常用到的信息&#xff1b;这样一来&#xff0c;…

【Git】--Part4--多人协作

在之前的Git博客中&#xff0c;已经把Git本地相关的操作以及远程操作的介绍完了。如下&#xff1a; Git–Part1–基础操作 - 掘金 (juejin.cn)Git–Part2–分支管理 - 掘金 (juejin.cn)Git–Part3–远程操作 & 配置 & 标签管理 - 掘金 (juejin.cn) 这篇文章会介绍两种…

[FreeRTOS 基础知识] 互斥访问与回环队列 概念

文章目录 为什么需要互斥访问&#xff1f;使用队列实现互斥访问休眠和唤醒机制环形缓冲区 为什么需要互斥访问&#xff1f; 在裸机中&#xff0c;假设有两个函数&#xff08;func_A, func_B&#xff09;都要修改a的值&#xff08;a&#xff09;&#xff0c;那么将a定义为全局变…

音视频的Buffer处理

最近在做安卓下UVC的一个案子。正好之前搞过ST方案的开机广告&#xff0c;这个也是我少数最后没搞成功的项目。当时也有点客观原因&#xff0c;当时ST要退出机顶盒市场&#xff0c;所以一切的支持都停了&#xff0c;当时啃他家播放器几十万行的代码&#xff0c;而且几乎没有文档…

C++ | Leetcode C++题解之第179题最大数

题目&#xff1a; 题解&#xff1a; class Solution { public:string largestNumber(vector<int> &nums) {sort(nums.begin(), nums.end(), [](const int &x, const int &y) {return to_string(x) to_string(y) > to_string(y) to_string(x);});if (nu…