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 环境下的透传类型或其他厂商设备的支持,可以通过 Flutter 与 Native 通信来由原生实现;
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());
},
);
2.2 点击
通知类 Push 消息点击是通过 xgPushClickAction() 方法进行回调,之后的业务逻辑可以根据消息返回的信息进行处理;小菜为了适配其他的 Push 类型,调整了点击后的操作,默认为启动 app,小菜通常在【附加参数】中添加 Json 进行数据解析,在进行之后的业务处理;
XgFlutterPlugin().addEventHandler(
xgPushClickAction: (Map<String, dynamic> msg) async {
print(“HomePage -> xgPushClickAction -> $msg”);
_showDialog(‘通知类消息点击’, msg.toString());
},
);
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](https://p3-juejin.byteimg.com/tos-
cn-i-k3u1fbpfcp/ca4901daafb94464b63edb2066c9de99~tplv-k3u1fbpfcp-zoom-1.image)
3.2 展示
Flutter 端在接收到 透传类 Push 消息时,发送 MethodChannel 到 Android Native,Native 端在解析对应参数进行 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();
}
}
});
}
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)
.setContentIntent(pendingIntent)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setAutoCancel(true)
.build();
notificationManager.notify(notificationId, notification);
}
3.4 注意事项
小菜在 PendingIntent 中传递的页面依旧是 MainActivity,可以根据具体的业务逻辑启动专门的中转页面;其中使用 MainActivity 时需要,因为设置了 Flag 为 Intent.FLAG_ACTIVITY_NEW_TASK 因此注意数据的接收通过 onNewIntent 进行接收;
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent != null && intent.getExtras() != null && intent.getExtras().containsKey(“push_extras”)) {
String extras = intent.getStringExtra(“push_extras”);
if (mResult != null) {
mResult.success(extras);
}
}
}
小菜对于 Flutter TPNS 中很多高级方法还未做尝试,仅实现最基本的通知类和透传类 Push 的接收展示点击等;如有错误请多多指导!
来源: 阿策小和尚
最后
小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
如果你需要这些资料, ⬅ 专栏获取
[外链图片转存中…(img-DlMlirfQ-1719305720341)]
[外链图片转存中…(img-IHBOsrT3-1719305720342)]
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
如果你需要这些资料, ⬅ 专栏获取