当前位置:   article > 正文

flutter 极光推送配置流程(极光通道/华为厂商/IOS)_极光推送厂商通道

极光推送厂商通道

极光推送配置流程

极光通道(在线)

配置时间 2024年3月11日

创建应用

在这里插入图片描述
应用列表 - 创建应用
在这里插入图片描述
Android - 选中消息推送 - 下一步

创建Flutter项目
在这里插入图片描述
填写包名
在这里插入图片描述

创建完成
在这里插入图片描述

项目配置

运行命令行 flutter pub add jpush_flutter
在这里插入图片描述

Android -> app -> build.gradle 更改JPUSH_APPKEY的值
在这里插入图片描述
在这里插入图片描述

工具类注册JPush Android

import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:jpush_flutter/jpush_flutter.dart';

class JPushUtil {
  JPushUtil._internal();

  static final _instance = JPushUtil._internal();

  factory JPushUtil() => _instance;

  final JPush jPush = JPush();

  Future<void> initPlatformState() async {
    String? platformVersion;
    try {
      jPush.addEventHandler(
        onReceiveNotification: (message) async {
          print("flutter onReceiveNotification: $message");
        },
        onOpenNotification: (message) async {
          print("flutter onOpenNotification: $message");
        },
        onReceiveMessage: (message) async {
          print("flutter onReceiveMessage: $message");
        },
        onReceiveNotificationAuthorization: (message) async {
          print("flutter onReceiveNotificationAuthorization: $message");
        },
        onConnected: (message) {
          print("flutter onConnected: $message");
          return Future(() => null);
        },
      );
    } on PlatformException {
      platformVersion = 'Failed to get platform version.';
      print(platformVersion);
    }
    jPush.isNotificationEnabled().then((bool value) {
      print("通知授权是否打开: $value");
      if (!value) {
        Get.snackbar(
          "提示",
          "没有通知权限,点击跳转打开通知设置界面",
          duration: const Duration(seconds: 6),
          onTap: (_) {
            jPush.openSettingsForNotification();
          },
        );
      }
    }).catchError((onError) {
      print("通知授权是否打开: ${onError.toString()}");
    });

    jPush.enableAutoWakeup(enable: true);
    jPush.setup(
      appKey: '7f684a39ff1f95ef1657acdd',
      production: true,
      debug: true,
    );
    jPush.applyPushAuthority(
      const NotificationSettingsIOS(
        sound: true,
        alert: true,
        badge: true,
      ),
    );
    final rid = await jPush.getRegistrationID();
    print("flutter getRegistrationID: $rid");
  }

  setAlias(String aliasStr) {
    final alias = jPush.setAlias(aliasStr);
    print("Alias is $alias");
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76

main.dart

import 'package:demonstration_project/jPushUtil.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Flutter 极光推送',
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  
  void initState() {
    JPushUtil().initPlatformState();
    super.initState();
  }

  
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text("极光推送配置"),
      ),
    );
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

运行项目

运行项目在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文件
在这里插入图片描述

buildscript {
    ext.kotlin_version = '1.9.0'
    repositories {
        google()
        mavenCentral()
        // 配置HMS Core SDK的Maven仓地址。
        maven { url 'https://developer.huawei.com/repo/' }
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:7.1.3'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'com.huawei.agconnect:agcp:1.6.0.300'
    }
}
allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url 'https://developer.huawei.com/repo/' }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

若出现以下报错
在这里插入图片描述
那说明漏了配置AGC插件,参考相关链接
在这里插入图片描述
接着添加依赖
在这里插入图片描述

dependencies {
    // 极光推送  'cn.jiguang.sdk:jpush:5.2.3' 和 'cn.jiguang.sdk.plugin:huawei:5.2.3' 版本需一致
    implementation 'cn.jiguang.sdk:jpush:5.2.3'
    implementation 'com.huawei.agconnect:agconnect-core:1.8.1.300'
    implementation 'com.huawei.hms:push:6.12.0.300'
    implementation 'cn.jiguang.sdk.plugin:huawei:5.2.3' // 这里版本一定要和极光插件版本一致!!!
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

最后配置签名文件,若出现以下错误,就代表没有配置签名
在这里插入图片描述
在这里插入图片描述

    signingConfigs {
        debug {
            //keystore中key的别名
            keyAlias 'demo_key'
            //keystore中key的密码
            keyPassword '123456'
            //keystore的文件路径,可以是绝对路径也可以是相对路径
            storeFile file('../demostration_project_key.jks')
            //keystore的密码l
            storePassword '123456'
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

最后在极光平台厂商通道配置设置App ID 和App Secret,并启用
在这里插入图片描述

华为平台配置

在这里插入图片描述
回执配置参考链接
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里的自分类是华为控制滥发消息的,需要设置一下,参考链接
在这里插入图片描述
选一个要发的场景
在这里插入图片描述
填写信息,和场景相关的信息
在这里插入图片描述
在这里插入图片描述
激活功能
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

若出现以下这句,就代表配置成功了
在这里插入图片描述
这里的检测会有延迟,真机测试能离线收到消息就ok
在这里插入图片描述

错误集锦

1、版本不一致

1、极光厂商插件版本和JPush版本不一致,即便输出huawei token,也是收不到离线消息的

    // 极光推送  'cn.jiguang.sdk:jpush:5.2.3' 和 'cn.jiguang.sdk.plugin:huawei:5.2.3' 版本需一致
    implementation 'cn.jiguang.sdk:jpush:5.2.3'
    // 华为
    implementation 'com.huawei.agconnect:agconnect-core:1.8.1.300'
    implementation 'com.huawei.hms:push:6.12.0.300'
    implementation 'cn.jiguang.sdk.plugin:huawei:5.2.3'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2、权限

网络权限记得加上

<uses-permission android:name="android.permission.INTERNET" />
  • 1

Ios

官方配置参考链接

Push

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Podfile

在这里插入图片描述

  pod 'JPush'
  pod 'JOperate'
  pod 'JCore'
  • 1
  • 2
  • 3

终端 pod install
在这里插入图片描述

Token Authentication配置

在这里插入图片描述
developer.apple.com
在这里插入图片描述
后续步骤直接参考上面的链接,很详细
最后获取到的
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

运行项目

在这里插入图片描述
配置完成

推送API

推送API参考文档

鉴权方式

用冒号拼接appkey和masterSecret,并用base64加密该字符串,最终再拼上"Basic "

    final content = utf8.encode("$appKey:$masterSecret");
    String base64AuthString = "Basic ${base64Encode(content)}";
  • 1
  • 2

测试代码

import 'dart:convert';
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '推送',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: '信息推送'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final String appKey = "XXX";
  final String masterSecret = "XXX";
  late String base64AuthString;
  final Dio dio = Dio();

  late String notificationAlert;
  late String notificationTitle;
  late String notificationAudienceAlias;

  
  void initState() {
    final content = utf8.encode("$appKey:$masterSecret");
    base64AuthString = "Basic ${base64Encode(content)}";
    super.initState();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: ListView(
            children: [
              TextField(
                decoration: const InputDecoration(
                  labelText: "主标题",
                  hintText: "请输入...",
                ),
                onChanged: (s) {
                  notificationAlert = s;
                },
              ),
              TextField(
                decoration: const InputDecoration(
                  labelText: "副标题",
                  hintText: "请输入...",
                ),
                onChanged: (s) {
                  notificationTitle = s;
                },
              ),
              TextField(
                decoration: const InputDecoration(
                  labelText: "别名",
                  hintText: "请输入...",
                ),
                onChanged: (s) {
                  notificationAudienceAlias = s;
                },
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: ElevatedButton(
                  onPressed: () {
                    showDialog(
                        context: context,
                        builder: (context) {
                          return SimpleDialog(
                            title: const Text("确定发送?"),
                            children: [
                              SimpleDialogOption(
                                child: const Text("确定"),
                                onPressed: () {
                                  pushMessage(
                                    notificationAlert: notificationAlert,
                                    notificationTitle: notificationTitle,
                                    notificationAudienceAlias: [
                                      notificationAudienceAlias
                                    ],
                                  );
                                  Navigator.of(context).pop();
                                },
                              ),
                              SimpleDialogOption(
                                child: const Text("取消"),
                                onPressed: () {
                                  Navigator.of(context).pop();
                                },
                              )
                            ],
                          );
                        });
                  },
                  child: const Text("推送消息"),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  /// 推送
  pushMessage({
    required String notificationAlert,
    required String notificationTitle,
    required List<String> notificationAudienceAlias,
  }) async {
    const String url = "https://api.jpush.cn/v3/push";
    var data = json.encode({
      "platform": ["android", "ios"],
      "inapp_message": {"inapp_message": false},
      "options": {
        "classification": 0,
        "time_to_live": 86400,
        "apns_production": false,
        "third_party_channel": {
          "huawei": {
            "skip_quota": false,
            "distribution": "secondary_push",
            "channel_id": "",
            "category": "DEVICE_REMINDER",
            "receipt_id": ""
          }
        }
      },
      "notification": {
        "alert": notificationAlert,
        "android": {
          "alert": notificationAlert,
          "title": notificationTitle,
          "intent": {"url": "intent:#Intent;action=android.intent.action.MAIN;end"},
          "sound": "",
          "priority": 0,
          "category": "",
          "alert_type": 7,
          "style": 0,
          "builder_id": 0,
          "large_icon": "",
          "badge_add_num": 1,
          "extras": {
            "param": "123"
          }
        },
        "ios": {
          "alert": {
            "title": notificationAlert,
            "body": notificationTitle,
          },
          "content-available": 0,
          "mutable-content": 1,
          "sound": "default",
          "badge": "+1",
          "thread-id": "",
          "interruption-level": "active",
          "filter-criteria": "",
          "extras": {
            "参数": "A"
          }
        }
      },
      "audience": {
        "alias": notificationAudienceAlias,
      }
    });
    final response = await dio.request(
      url,
      data: data,
      options: Options(
        headers: {
          HttpHeaders.authorizationHeader: base64AuthString,
        },
        method: "POST",
      ),
    );
    print(response.data.toString());
  }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/493899
推荐阅读
相关标签
  

闽ICP备14008679号