ToB企服应用市场:ToB评测及商务社交产业平台

标题: 【Flutter】极光推送配置流程(极光通道/华为厂商/IOS) 章一 [打印本页]

作者: 万万哇    时间: 2024-7-18 03:12
标题: 【Flutter】极光推送配置流程(极光通道/华为厂商/IOS) 章一
极光推送配置流程
干系文章

推送配置共三篇(如下链接)
【Flutter】极光推送配置流程(极光通道/华为厂商/IOS) 章一
【Flutter】极光推送配置流程(小米厂商通道) 章二
【Flutter】极光推送配置流程(VIVO/OPPO/荣耀厂商通道) 章三
极光通道(在线)

配置时间 2024年3月11日
创建应用


应用列表 - 创建应用

Android - 选中消息推送 - 下一步
创建Flutter项目

填写包名

创建完成

项目配置

运行下令行 flutter pub add jpush_flutter

Android -> app -> build.gradle 更改JPUSH_APPKEY的值


工具类注册JPush Android
  1. import 'package:flutter/services.dart';
  2. import 'package:get/get.dart';
  3. import 'package:jpush_flutter/jpush_flutter.dart';
  4. class JPushUtil {
  5.   JPushUtil._internal();
  6.   static final _instance = JPushUtil._internal();
  7.   factory JPushUtil() => _instance;
  8.   final JPush jPush = JPush();
  9.   Future<void> initPlatformState() async {
  10.     String? platformVersion;
  11.     try {
  12.       jPush.addEventHandler(
  13.         onReceiveNotification: (message) async {
  14.           print("flutter onReceiveNotification: $message");
  15.         },
  16.         onOpenNotification: (message) async {
  17.           print("flutter onOpenNotification: $message");
  18.         },
  19.         onReceiveMessage: (message) async {
  20.           print("flutter onReceiveMessage: $message");
  21.         },
  22.         onReceiveNotificationAuthorization: (message) async {
  23.           print("flutter onReceiveNotificationAuthorization: $message");
  24.         },
  25.         onConnected: (message) {
  26.           print("flutter onConnected: $message");
  27.           return Future(() => null);
  28.         },
  29.       );
  30.     } on PlatformException {
  31.       platformVersion = 'Failed to get platform version.';
  32.       print(platformVersion);
  33.     }
  34.     jPush.isNotificationEnabled().then((bool value) {
  35.       print("通知授权是否打开: $value");
  36.       if (!value) {
  37.         Get.snackbar(
  38.           "提示",
  39.           "没有通知权限,点击跳转打开通知设置界面",
  40.           duration: const Duration(seconds: 6),
  41.           onTap: (_) {
  42.             jPush.openSettingsForNotification();
  43.           },
  44.         );
  45.       }
  46.     }).catchError((onError) {
  47.       print("通知授权是否打开: ${onError.toString()}");
  48.     });
  49.     jPush.enableAutoWakeup(enable: true);
  50.     jPush.setup(
  51.       appKey: '7f684a39ff1f95ef1657acdd',
  52.       production: true,
  53.       debug: true,
  54.     );
  55.     jPush.applyPushAuthority(
  56.       const NotificationSettingsIOS(
  57.         sound: true,
  58.         alert: true,
  59.         badge: true,
  60.       ),
  61.     );
  62.     final rid = await jPush.getRegistrationID();
  63.     print("flutter getRegistrationID: $rid");
  64.   }
  65.   setAlias(String aliasStr) {
  66.     final alias = jPush.setAlias(aliasStr);
  67.     print("Alias is $alias");
  68.   }
  69. }
复制代码
main.dart
  1. import 'package:demonstration_project/jPushUtil.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:get/get.dart';
  4. void main() {
  5.   runApp(const MyApp());
  6. }
  7. class MyApp extends StatelessWidget {
  8.   const MyApp({super.key});
  9.   // This widget is the root of your application.
  10.   @override
  11.   Widget build(BuildContext context) {
  12.     return GetMaterialApp(
  13.       title: 'Flutter 极光推送',
  14.       home: HomePage(),
  15.     );
  16.   }
  17. }
  18. class HomePage extends StatefulWidget {
  19.   @override
  20.   State<HomePage> createState() => _HomePageState();
  21. }
  22. class _HomePageState extends State<HomePage> {
  23.   @override
  24.   void initState() {
  25.     JPushUtil().initPlatformState();
  26.     super.initState();
  27.   }
  28.   @override
  29.   Widget build(BuildContext context) {
  30.     return const Scaffold(
  31.       body: Center(
  32.         child: Text("极光推送配置"),
  33.       ),
  34.     );
  35.   }
  36. }
复制代码
运行项目

运行项目在Android端,有getRegistrationID,则注册成功

测试接收推送之前,先打开接收关照的权限

在极光平台检测集成

推送消息

平台推送

直接在平台客户端输入对应的数值来推送消息


注:当APP被杀死后,极光通道的推送就不能实时收到了,以是要配置厂商通道
推送API

通过接口调用推送
厂商通道(华为)

创建项目 创建应用

应用服务 - PUSH


继承

选择中国

开通推送服务


添加应用

输入干系信息

下载agconnect-services.json

放到应用级目录下

SHA256证书指纹


天生签名jks

天生签名文件的参考文档链接

创建新的Key





天生签名证书指纹

** keytool -list -v -keystore ./demostration_project_key.jks**

配置SHA256证书指纹


项目配置

若出现以下报错

修改Manifest.xml文件

修改android/build.gradle文件

  1. buildscript {
  2.     ext.kotlin_version = '1.9.0'
  3.     repositories {
  4.         google()
  5.         mavenCentral()
  6.         // 配置HMS Core SDK的Maven仓地址。
  7.         maven { url 'https://developer.huawei.com/repo/' }
  8.     }
  9.     dependencies {
  10.         classpath 'com.android.tools.build:gradle:7.1.3'
  11.         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
  12.         classpath 'com.huawei.agconnect:agcp:1.6.0.300'
  13.     }
  14. }
  15. allprojects {
  16.     repositories {
  17.         google()
  18.         mavenCentral()
  19.         maven { url 'https://developer.huawei.com/repo/' }
  20.     }
  21. }
复制代码
若出现以下报错

那说明漏了配置AGC插件,参考干系链接

接着添加依靠

  1. dependencies {
  2.     // 极光推送  'cn.jiguang.sdk:jpush:5.2.3' 和 'cn.jiguang.sdk.plugin:huawei:5.2.3' 版本需一致
  3.     implementation 'cn.jiguang.sdk:jpush:5.2.3'
  4.     implementation 'com.huawei.agconnect:agconnect-core:1.8.1.300'
  5.     implementation 'com.huawei.hms:push:6.12.0.300'
  6.     implementation 'cn.jiguang.sdk.plugin:huawei:5.2.3' // 这里版本一定要和极光插件版本一致!!!
  7. }
复制代码
最后配置签名文件,若出现以下错误,就代表没有配置签名


  1.     signingConfigs {
  2.         debug {
  3.             //keystore中key的别名
  4.             keyAlias 'demo_key'
  5.             //keystore中key的密码
  6.             keyPassword '123456'
  7.             //keystore的文件路径,可以是绝对路径也可以是相对路径
  8.             storeFile file('../demostration_project_key.jks')
  9.             //keystore的密码l
  10.             storePassword '123456'
  11.         }
  12.     }
复制代码
最后在极光平台厂商通道配置设置App ID 和App Secret,并启用

华为平台配置


回执配置参考链接



这里的自分类是华为控制滥发消息的,需要设置一下,参考链接

选一个要发的场景

填写信息,和场景干系的信息


激活功能



找一台华为手机来运行项目

若出现以下这句,就代表配置成功了

这里的检测会有延迟,真机测试能离线收到消息就ok

错误集锦

1、版本不同等

1、极光厂商插件版本和JPush版本不同等,即便输出huawei token,也是收不到离线消息的
  1.     // 极光推送  'cn.jiguang.sdk:jpush:5.2.3' 和 'cn.jiguang.sdk.plugin:huawei:5.2.3' 版本需一致
  2.     implementation 'cn.jiguang.sdk:jpush:5.2.3'
  3.     // 华为
  4.     implementation 'com.huawei.agconnect:agconnect-core:1.8.1.300'
  5.     implementation 'com.huawei.hms:push:6.12.0.300'
  6.     implementation 'cn.jiguang.sdk.plugin:huawei:5.2.3'
复制代码
2、权限

网络权限记得加上
  1. <uses-permission android:name="android.permission.INTERNET" />
复制代码
Ios

官方配置参考链接
Push




Podfile


  1.   pod 'JPush'
  2.   pod 'JOperate'
  3.   pod 'JCore'
复制代码
终端 pod install

Token Authentication配置


developer.apple.com

后续步调直接参考上面的链接,很具体
最后获取到的



运行项目


配置完成
推送API

推送API参考文档
鉴权方式

用冒号拼接appkey和masterSecret,并用base64加密该字符串,终极再拼上"Basic "
  1.     final content = utf8.encode("$appKey:$masterSecret");
  2.     String base64AuthString = "Basic ${base64Encode(content)}";
复制代码
测试代码
  1. import 'dart:convert';
  2. import 'dart:io';
  3. import 'package:dio/dio.dart';
  4. import 'package:flutter/material.dart';
  5. void main() {
  6.   runApp(const MyApp());
  7. }
  8. class MyApp extends StatelessWidget {
  9.   const MyApp({super.key});
  10.   @override
  11.   Widget build(BuildContext context) {
  12.     return MaterialApp(
  13.       title: '推送',
  14.       theme: ThemeData(
  15.         colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
  16.         useMaterial3: true,
  17.       ),
  18.       home: const MyHomePage(title: '信息推送'),
  19.     );
  20.   }
  21. }
  22. class MyHomePage extends StatefulWidget {
  23.   const MyHomePage({super.key, required this.title});
  24.   final String title;
  25.   @override
  26.   State<MyHomePage> createState() => _MyHomePageState();
  27. }
  28. class _MyHomePageState extends State<MyHomePage> {
  29.   final String appKey = "XXX";
  30.   final String masterSecret = "XXX";
  31.   late String base64AuthString;
  32.   final Dio dio = Dio();
  33.   late String notificationAlert;
  34.   late String notificationTitle;
  35.   late String notificationAudienceAlias;
  36.   @override
  37.   void initState() {
  38.     final content = utf8.encode("$appKey:$masterSecret");
  39.     base64AuthString = "Basic ${base64Encode(content)}";
  40.     super.initState();
  41.   }
  42.   @override
  43.   Widget build(BuildContext context) {
  44.     return Scaffold(
  45.       appBar: AppBar(
  46.         backgroundColor: Theme.of(context).colorScheme.inversePrimary,
  47.         title: Text(widget.title),
  48.       ),
  49.       body: Center(
  50.         child: Padding(
  51.           padding: const EdgeInsets.all(8.0),
  52.           child: ListView(
  53.             children: [
  54.               TextField(
  55.                 decoration: const InputDecoration(
  56.                   labelText: "主标题",
  57.                   hintText: "请输入...",
  58.                 ),
  59.                 onChanged: (s) {
  60.                   notificationAlert = s;
  61.                 },
  62.               ),
  63.               TextField(
  64.                 decoration: const InputDecoration(
  65.                   labelText: "副标题",
  66.                   hintText: "请输入...",
  67.                 ),
  68.                 onChanged: (s) {
  69.                   notificationTitle = s;
  70.                 },
  71.               ),
  72.               TextField(
  73.                 decoration: const InputDecoration(
  74.                   labelText: "别名",
  75.                   hintText: "请输入...",
  76.                 ),
  77.                 onChanged: (s) {
  78.                   notificationAudienceAlias = s;
  79.                 },
  80.               ),
  81.               Padding(
  82.                 padding: const EdgeInsets.all(8.0),
  83.                 child: ElevatedButton(
  84.                   onPressed: () {
  85.                     showDialog(
  86.                         context: context,
  87.                         builder: (context) {
  88.                           return SimpleDialog(
  89.                             title: const Text("确定发送?"),
  90.                             children: [
  91.                               SimpleDialogOption(
  92.                                 child: const Text("确定"),
  93.                                 onPressed: () {
  94.                                   pushMessage(
  95.                                     notificationAlert: notificationAlert,
  96.                                     notificationTitle: notificationTitle,
  97.                                     notificationAudienceAlias: [
  98.                                       notificationAudienceAlias
  99.                                     ],
  100.                                   );
  101.                                   Navigator.of(context).pop();
  102.                                 },
  103.                               ),
  104.                               SimpleDialogOption(
  105.                                 child: const Text("取消"),
  106.                                 onPressed: () {
  107.                                   Navigator.of(context).pop();
  108.                                 },
  109.                               )
  110.                             ],
  111.                           );
  112.                         });
  113.                   },
  114.                   child: const Text("推送消息"),
  115.                 ),
  116.               ),
  117.             ],
  118.           ),
  119.         ),
  120.       ),
  121.     );
  122.   }
  123.   /// 推送
  124.   pushMessage({
  125.     required String notificationAlert,
  126.     required String notificationTitle,
  127.     required List<String> notificationAudienceAlias,
  128.   }) async {
  129.     const String url = "https://api.jpush.cn/v3/push";
  130.     var data = json.encode({
  131.       "platform": ["android", "ios"],
  132.       "inapp_message": {"inapp_message": false},
  133.       "options": {
  134.         "classification": 0,
  135.         "time_to_live": 86400,
  136.         "apns_production": false,
  137.         "third_party_channel": {
  138.           "huawei": {
  139.             "skip_quota": false,
  140.             "distribution": "secondary_push",
  141.             "channel_id": "",
  142.             "category": "DEVICE_REMINDER",
  143.             "receipt_id": ""
  144.           }
  145.         }
  146.       },
  147.       "notification": {
  148.         "alert": notificationAlert,
  149.         "android": {
  150.           "alert": notificationAlert,
  151.           "title": notificationTitle,
  152.           "intent": {"url": "intent:#Intent;action=android.intent.action.MAIN;end"},
  153.           "sound": "",
  154.           "priority": 0,
  155.           "category": "",
  156.           "alert_type": 7,
  157.           "style": 0,
  158.           "builder_id": 0,
  159.           "large_icon": "",
  160.           "badge_add_num": 1,
  161.           "extras": {
  162.             "param": "123"
  163.           }
  164.         },
  165.         "ios": {
  166.           "alert": {
  167.             "title": notificationAlert,
  168.             "body": notificationTitle,
  169.           },
  170.           "content-available": 0,
  171.           "mutable-content": 1,
  172.           "sound": "default",
  173.           "badge": "+1",
  174.           "thread-id": "",
  175.           "interruption-level": "active",
  176.           "filter-criteria": "",
  177.           "extras": {
  178.             "参数": "A"
  179.           }
  180.         }
  181.       },
  182.       "audience": {
  183.         "alias": notificationAudienceAlias,
  184.       }
  185.     });
  186.     final response = await dio.request(
  187.       url,
  188.       data: data,
  189.       options: Options(
  190.         headers: {
  191.           HttpHeaders.authorizationHeader: base64AuthString,
  192.         },
  193.         method: "POST",
  194.       ),
  195.     );
  196.     print(response.data.toString());
  197.   }
  198. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4