一、需求描述
项目中需要接入极光推送SDK,实现从Java服务端推送消息到Android车机端,以下实现的功能主要是安卓端的,IOS端的虽然代码也兼容了,但是不在本次讨论范围内。以下是具体的实现过程。
二、极光推送介绍
极光推送是一款提供高效、安全、可靠的移动推送服务的云端平台,帮助用户快速实现安全的移动消息推送,它能够支持 Android、iOS 和 Web 等多个平台,为客户端 App 提供推送服务。它可以帮助开发者快速开发出一款功能强大、性能卓越的移动 App,为用户提供更便捷的服务。
2.1 如何申请车机key
直接登录https://www.jiguang.cn/ 极光推送的官网,进入开发者平台 - 应用管理,点击新建按钮
选择消息推送,再点击下一步
点击产品设置,输入应用包名,这个最好跟开发车机的同事要到。
最后选择SDK下载即可
回应用的首页,可以看到对应的key+secret
注意:
AppKey + Master Secret是需要配置到我们Java服务端后台的代码中,AppKey 是需要配置到车机端中的。
2.2 两种通知方式
因为极光推送支持多种推送方式,包括以下四种吧
2.2.1 通知消息
notification:通知,通知消息会触发安卓系统的通知消息,“通知”对象,是一条推送的实体内容对象之一(另一个是“消息”),是会作为“通知”推送到客户端的。
测试发送NotificationMessage,
{
notificationId=513213292,
msgId='18100617073600973',
appkey='appkey',
notificationContent='车机同事,如有疑问,请联系XXX,XXX极光服务端来的推送',
notificationAlertType=7,
notificationTitle='这是XXX极光服务端来的推送',
notificationSmallIcon='',
notificationLargeIcon='',
notificationExtras='{}',
notificationStyle=0,
notificationBuilderId=0,
notificationBigText='',
notificationBigPicPath='',
notificationInbox='',
notificationPriority=0,
notificationCategory='',
developerArg0='',
platform=0,
notificationChannelId='',
displayForeground='',
notificationType=0',
inAppMsgType=1',
inAppMsgShowType=2',
inAppMsgShowPos=0',
inAppMsgTitle=,
inAppMsgContentBody=,
inAppType=0
}
2.2.2 自定义消息
应用内消息,又称作:自定义消息,透传消息。
此部分内容不会展示到通知栏上,JPush SDK 收到消息内容后透传给 App,需要 App 自行处理。
因为项目往往都会有定制UI的需求,所以此处我们选择的“自定义消息”。
测试发送CustomMessage,
{
messageId='18100616954706161',
extra='',
message='你好,我是XXXX自定义的内容20230220 1724',
contentType='',
title='',
senderId='b1b6d54ffc7d36743d2cd208',
appId='com.xxx.xxx.xxx.xxx',
platform='0'
}
2.3 方案流程图
因为本指引聚焦在Cloud Server端的编程,其他模块不在本文中描述。
三、实现逻辑
3.1 定义测试的Controller
用于触发JiGuangUtil,此处支持两种通知方式,triggerNotificationMessage 、 triggerCustomMessage
@RestController
@RequestMapping("/jpush")
public class JpushController {
@GetMapping("/triggerNotificationMessage")
public JSONObject triggerNotificationMessage() {
//推送内容(标题与内容)
JSONObject json = new JSONObject();
json.set("title", "我是XXXX项目的推送title");
json.set("content", "我是XXXX项目的推送content");
//单次推送的registerId列表
List<String> tokenList = new ArrayList<>();
String regId = "XXXXXXXXXXXXXXXXXXXXXXXX";
tokenList.add(regId);
//推送的自定义信息
String action = "other msg";
return JiGuangUtil.pushJiGuangOnTokenList(json, tokenList, action);
}
@GetMapping("/triggerCustomMessage")
public JSONObject trigger() {
//推送内容(标题与内容)
JSONObject dataJson = new JSONObject();
dataJson.set("title", "我是XXXX项目的推送title 18:32");
dataJson.set("message", "我是XXXX项目的推送的自定义message 18:32");
dataJson.set("contentType", "XXXXX推送类型 18:32");
//单次推送的registerId列表
List<String> regIdList = new ArrayList<>();
String regId = "XXXXXXXXXXXXXXXXXXXXXXXX";
regIdList.add(regId);
//推送的自定义信息
String extrasInfo = "extrasInfo";
return JiGuangUtil.pushJiGuangCustomMessage(dataJson, regIdList, extrasInfo);
}
}
3.2 定义极光推送工具类 - JiguangUtil
public class JiGuangUtil {
private static final Log LOGGER = LogFactory.get();
private static final int MAX_SIZE = 999;
private static final String PROD_EVN = "prod";
private static final String SAND_EVN = "sand";
private static final char ANDROID_EVN = '0';
private static final char IOS_EVN = '1';
private static boolean pushEnvironment = false;
static {
Props props = new Props("application.properties");
String pushEvo = props.getStr("XXXXX.XXXXX", SAND_EVN);
pushEnvironment = PROD_EVN.equals(pushEvo) ? true : false;
}
/**
* Android沙箱
*/
private static final String APP_KEY_ANDROID = "XXXXX";
private static final String SECRET_ANDROID = "XXXXX";
/**
* Android生产
*/
private static final String APP_KEY_ANDROID_PROD = "XXXXX";
private static final String SECRET_ANDROID_PROD = "XXXXX";
/**
* IOS
*/
private static final String APP_KEY_IOS = "XXXXX";
private static final String SECRET_IOS = "XXXXX";
/**
* 推送地址极光
*/
private static final String PUSH_URL = "https://api.jpush.cn/v3/push";
/**
* 设置生产环境 极光推送只是对ios有效
*/
private static final boolean PUSH_ENVIRONMENT_PROD = Boolean.TRUE;
/**
* 按regIdList进行安卓推送(通知消息)
*/
public static JSONObject pushJiGuangOnTokenList(JSONObject json,
List<String> regIdList,
String action) {
List<String> androidReg = regIdList.parallelStream()
.filter(x -> StrUtil.isNotBlank(x))
.filter(x -> ANDROID_EVN == x.charAt(2))
.distinct()
.collect(Collectors.toList());
List<String> iosReg = regIdList.parallelStream()
.filter(x -> StrUtil.isNotBlank(x))
.filter(x -> IOS_EVN == x.charAt(2))
.distinct()
.collect(Collectors.toList());
List<List<String>> androidRegIdList = CollUtil.split(androidReg, MAX_SIZE);
List<List<String>> iosRegIdList = CollUtil.split(iosReg, MAX_SIZE);
LOGGER.info("JiGuang push count user,android={},iOS={}", androidReg.size(), iosReg.size());
androidRegIdList.stream().filter(x -> CollUtil.isNotEmpty(x)).forEach(x -> {
if (pushEnvironment) {
// 安卓推送生产
pushMessage(json, action, x, APP_KEY_ANDROID_PROD, SECRET_ANDROID_PROD, PlatFormEnum.ANDROID, PUSH_ENVIRONMENT_PROD);
} else {
// 安卓推送沙箱
pushMessage(json, action, x, APP_KEY_ANDROID, SECRET_ANDROID, PlatFormEnum.ANDROID, PUSH_ENVIRONMENT_PROD);
}
});
// IOS推送生产/沙箱
iosRegIdList.stream().filter(x -> CollUtil.isNotEmpty(x))
.forEach(x -> pushMessage(json, action, x, APP_KEY_IOS, SECRET_IOS, PlatFormEnum.IOS, pushEnvironment));
return JSONUtil.createObj().set("code", CommonRespDef.ERROR_CODE_0_DESP);
}
/**
* @param json 推送内容(标题与内容)
* @param action 自定义内容
* @param regIds 单次推送的register_id数组
* @param appKey app_key
* @param masterSecret Secret
* @param systemName 操作系统名称;IOS、安卓
* @param environment 环境区分(IOS:false 测试环境、true:生产环境)
* @Description: 推送的内容封装
*/
private static void pushMessage(JSONObject json, String action, List<String> regIds,
String appKey, String masterSecret,
PlatFormEnum systemName, boolean environment) {
AppPushParam appPushParam = new AppPushParam();
// 设置推送的平台
List<PlatFormEnum> platformList = new ArrayList<PlatFormEnum>();
platformList.add(systemName);
appPushParam.setPlatform(platformList);
// 设置开发环境 极光推送只是对ios有效
appPushParam.setPushEnvironment(environment);
// 设置推送目标 如果不设置就是广播模式
Map<String, String[]> audience = new HashMap<String, String[]>();
String[] redIdArray = ArrayUtil.toArray(regIds, String.class);
// 指定设备的registration_id进行发送 "XXXXXXX"
audience.put("registration_id", redIdArray);
appPushParam.setAudience(audience);
// 安卓推送
JiGuangConfig appPushConfig = new JiGuangConfig(masterSecret, appKey, PUSH_URL);
// 推送弹窗的信息内容
appPushParam.setTitle(json.getStr("title"));
appPushParam.setMessage(json.getStr("content"));
// 推送的自定义信息
Map<String, String> homeExtrasInfo = new HashMap<String, String>();
homeExtrasInfo.put("action", action);
appPushParam.setExtras(homeExtrasInfo);
// 设置离线消息保留时长(秒)
appPushParam.setTimeToLive(60);
AppPushManger manger = new AppPushManger(new JiGuangPushImpl(appPushConfig));
manger.push(appPushParam);
}
/**
* 按regIdList进行安卓推送(自定义消息推送)
*/
public static JSONObject pushJiGuangCustomMessage(JSONObject dataJson,
List<String> regIdList,
String action) {
List<String> androidReg = regIdList.parallelStream()
.filter(x -> StrUtil.isNotBlank(x))
.filter(x -> ANDROID_EVN == x.charAt(2))
.distinct()
.collect(Collectors.toList());
List<List<String>> androidRegIdList = CollUtil.split(androidReg, MAX_SIZE);
LOGGER.info("JiGuang push count user,android={}", androidReg.size());
androidRegIdList.stream().filter(x -> CollUtil.isNotEmpty(x)).forEach(x -> {
if (pushEnvironment) {
// 安卓推送生产
pushCustomMessage(dataJson, action, x, APP_KEY_ANDROID_PROD, SECRET_ANDROID_PROD, PlatFormEnum.ANDROID, PUSH_ENVIRONMENT_PROD);
} else {
// 安卓推送沙箱
pushCustomMessage(dataJson, action, x, APP_KEY_ANDROID, SECRET_ANDROID, PlatFormEnum.ANDROID, PUSH_ENVIRONMENT_PROD);
}
});
return JSONUtil.createObj().set("code", CommonRespDef.ERROR_CODE_0_DESP);
}
private static void pushCustomMessage(JSONObject dataJson, String action, List<String> regIds,
String appKey, String masterSecret,
PlatFormEnum systemName, boolean environment) {
AppPushParamCustom appPushParamCustom = new AppPushParamCustom();
// 设置推送的平台
List<PlatFormEnum> platformList = new ArrayList<>();
platformList.add(systemName);
appPushParamCustom.setPlatform(platformList);
// 设置开发环境 极光推送只是对ios有效
appPushParamCustom.setPushEnvironment(environment);
// 设置推送目标 如果不设置就是广播模式
Map<String, String[]> audience = new HashMap<>();
String[] redIdArray = ArrayUtil.toArray(regIds, String.class);
// 指定设备的registration_id进行发送
audience.put("registration_id", redIdArray);
appPushParamCustom.setAudience(audience);
// 安卓推送
JiGuangConfig appPushConfig = new JiGuangConfig(masterSecret, appKey, PUSH_URL);
// 推送Message的内容
appPushParamCustom.setTitle(dataJson.getStr("title"));
appPushParamCustom.setMessage(dataJson.getStr("message"));
appPushParamCustom.setContentType(dataJson.getStr("contentType"));
// 推送的自定义信息
Map<String, String> extrasInfo = new HashMap<>();
extrasInfo.put("action", action);
appPushParamCustom.setExtras(extrasInfo);
AppPushManger manger = new AppPushManger(new JiGuangPushImpl(appPushConfig));
manger.pushCustomMessage(appPushParamCustom);
}
}
3.3 定义三个domain文件
3.3.1 AppPushManger
public class AppPushManger {
private IAppPush appPush;
public AppPushManger(IAppPush appPush) {
this.appPush = appPush;
}
public boolean push(AppPushParam appPushParam) {
return appPush.push(appPushParam);
}
public boolean pushCustomMessage(AppPushParamCustom appPushParamCustom) {
return appPush.pushCustomMessage(appPushParamCustom);
}
}
3.3.2 定义AppPushParam
@Getter
@Setter
public class AppPushParam {
/**
* 推送标题
*/
private String title;
/**
* 推送消息 空字符串,则表示不展示到通知栏。
*/
private String message;
/**
* 发送平台 android ios
*/
private List<PlatFormEnum> platform;
/**
* 推送目标 如果为null,则是广播
*/
private Map<String, String[]> audience;
/**
* 离线消息保留时长(秒)
*/
private int timeToLive;
/**
* True 表示推送生产环境,False 表示要推送开发环境
*/
private boolean pushEnvironment;
/**
* 额外的参数
*/
private Map<String, String> extras;
}
3.3.3 定义AppPushParamCustom
@Getter
@Setter
public class AppPushParamCustom {
/**
* 推送标题
*/
private String title;
/**
* 表示不展示到通知栏。
*/
private String message;
/**
* 发送平台 android ios
*/
private List<PlatFormEnum> platform;
/**
* 推送目标 如果为null,则是广播
*/
private Map<String, String[]> audience;
/**
* 额外的参数
*/
private Map<String, String> extras;
/**
* True 表示推送生产环境,False 表示要推送开发环境
*/
private boolean pushEnvironment;
/**
* 内容类型
*/
private String contentType;
/**
* 离线消息保留时长(秒)
*/
// private int timeToLive;
}
3.4 定义两个配置文件
3.4.1 定义AppPushConfig文件
public interface AppPushConfig {
public String getAppKey();
public String getPushUrl();
public String getMasterSecret();
}
3.4.2 定义JiGuangConfig文件
@Getter
@Setter
public class JiGuangConfig implements AppPushConfig {
private String masterSecret = "";
private String appKey = "";
private String pushUrl = "";
public JiGuangConfig(String masterSecret, String appKey, String pushUrl) {
super();
this.masterSecret = masterSecret;
this.appKey = appKey;
this.pushUrl = pushUrl;
}
}
3.6 定义推送服务的接口
/** 推送服务的接口 主要用于AppPushManger(门面)调用 */
public interface IAppPush {
/** app 推送通知消息服务 */
boolean push(AppPushParam appPushParam);
/** app 推送自定义消息服务 */
boolean pushCustomMessage(AppPushParamCustom appPushParamCustom);
}
3.7 定义推送服务的抽象类
推送服务IAppPush的push 方法具体实现类:认证、参数转换、调用推送
public abstract class AbstractAppPush implements IAppPush {
private static Log LOGGER = LogFactory.get();
protected IAppPushParamConverter appPushParamConverter;
protected AppPushConfig appPushConfig;
@Override
public boolean push(AppPushParam appPushParam) {
String pushParamsJsonStr = convertAppPushParam(appPushParam);
String authorization = getAuthorization(appPushConfig);
String returnJson = post(appPushConfig, authorization, pushParamsJsonStr);
if (returnJson != null) {
LOGGER.info("app push success:" + returnJson);
return true;
}
LOGGER.info("app push fail!");
return false;
}
@Override
public boolean pushCustomMessage(AppPushParamCustom appPushParamCustom) {
String pushParamsJsonStr = convertCustomMessageAppPushParam(appPushParamCustom);
String authorization = getAuthorization(appPushConfig);
String returnJson = post(appPushConfig, authorization, pushParamsJsonStr);
if (returnJson != null) {
LOGGER.info("app push custom message success:" + returnJson);
return true;
}
LOGGER.info("app push custom message fail!");
return false;
}
/** 认证信息获取 */
public abstract String getAuthorization(AppPushConfig appPushConfig);
/**参数转换 */
public abstract String convertAppPushParam(AppPushParam appPushParam);
/**(自定义推送内容)参数转换 */
public abstract String convertCustomMessageAppPushParam(AppPushParamCustom appPushParamCustom);
/**调用推送第三方服务 */
public abstract String post(AppPushConfig appPushConfig, String authorization, String pushParmJsonStr);
}
3.8 定义极光推送实现类JiGuangPushImpl
public class JiGuangPushImpl extends AbstractAppPush {
public JiGuangPushImpl(AppPushConfig appPushConfig) {
super.appPushParamConverter = new JiGuangAppPushParamConverter();
super.appPushConfig = appPushConfig;
}
@Override
public String getAuthorization(AppPushConfig appPushConfig) {
String appKey = appPushConfig.getAppKey();
String masterSecret = appPushConfig.getMasterSecret();
String base64_auth_string = Base64.encode(StrUtil.concat(true, appKey, ":", masterSecret).getBytes());
String authorization = "Basic " + base64_auth_string;
return authorization;
}
@Override
public String convertAppPushParam(AppPushParam appPushParam) {
String pushParamsJsonStr = appPushParamConverter.convert(appPushParam);
return pushParamsJsonStr;
}
@Override
public String convertCustomMessageAppPushParam(AppPushParamCustom appPushParamCustom) {
String pushParamsJsonStr = appPushParamConverter.convertCustomMessage(appPushParamCustom);
return pushParamsJsonStr;
}
@Override
public String post(AppPushConfig appPushConfig, String authorization, String pushParmJsonStr) {
HashMap<String, String> headMap = new HashMap<>();
headMap.put("Authorization", authorization.trim());
String returnJson = HttpUtil.createPost(appPushConfig.getPushUrl())
.addHeaders(headMap)
.timeout(1000)
.body(pushParmJsonStr)
.execute().body();
return returnJson;
}
}
3.9 定义两个转换工具的接口
public interface IAppPushParamConverter {
public String convert(AppPushParam appPushParam);
public String convertCustomMessage(AppPushParamCustom appPushParamCustom);
}
3.10 定义两个转换工具的实现类
极光推送AppPushParam 参数json数据转换类
public class JiGuangAppPushParamConverter implements IAppPushParamConverter {
private static Log LOGGER = LogFactory.get();
@Override
public String convert(AppPushParam appPushParam) {
JSONObject pushParamJson = new JSONObject();
List<PlatFormEnum> platformList = appPushParam.getPlatform();
Map<String, String[]> audienceMap = appPushParam.getAudience();
Map<String, String> extras = appPushParam.getExtras();
// 构建推送平台信息
JSONArray platform = buildPlatform(platformList, new JSONArray());
// 构建推送目标信息
JSONObject audience = buildAudience(audienceMap, new JSONObject());
// 构建安卓的推送信息
JSONObject notification = new JSONObject();
buildAndroidInfo(notification, extras, platformList, appPushParam);
buildIosInfo(notification, extras, platformList, appPushParam);
// 构建IOS参数信息
JSONObject options = new JSONObject();
buildOptions(options, appPushParam);
// 设置推送平台信息
setPlatform(platform, pushParamJson);
// 设置推送目标信息
setAudience(audience, pushParamJson);
// 设置推送信息
pushParamJson.set("notification", notification);
// 设置options信息
pushParamJson.set("options", options);
LOGGER.info("app push json:" + pushParamJson.toString());
return pushParamJson.toString();
}
@Override
public String convertCustomMessage(AppPushParamCustom appPushParamCustom) {
JSONObject pushParamJson = new JSONObject();
// 构建推送平台信息
List<PlatFormEnum> platformList = appPushParamCustom.getPlatform();
JSONArray platform = buildPlatform(platformList, new JSONArray());
// 设置推送平台信息
setPlatform(platform, pushParamJson);
// 构建推送目标信息
Map<String, String[]> audienceMap = appPushParamCustom.getAudience();
JSONObject audience = buildAudience(audienceMap, new JSONObject());
// 设置推送目标信息
setAudience(audience, pushParamJson);
// 构建安卓的推送信息
Map<String, String> extras = appPushParamCustom.getExtras();
pushParamJson.set("message", buildCustomMessageAndroidInfo(extras, platformList, appPushParamCustom));
LOGGER.info("app push android custom message json:" + JSONUtil.toJsonStr(pushParamJson));
return pushParamJson.toString();
}
private static void setAudience(JSONObject audience, JSONObject pushParamJson) {
pushParamJson.set("audience", audience == null ? "all" : audience);
}
private static void setPlatform(JSONArray platform, JSONObject pushParamJson) {
pushParamJson.set("platform", platform == null ? "all" : platform);
}
private static void buildOptions(JSONObject options, AppPushParam appPushParam) {
options.set("time_to_live", appPushParam.getTimeToLive());
options.set("apns_production", appPushParam.isPushEnvironment());
}
private static void buildIosInfo(JSONObject notification, Map<String, String> extras,
List<PlatFormEnum> platformList, AppPushParam appPushParam) {
if (platformList != null && platformList.size() > 0 && platformList.contains(PlatFormEnum.IOS)) {
// ios通知内容
JSONObject ios = new JSONObject();
// ios.set("alert", appPushParam.getMessage());
ios.set("alert", JSONUtil.createObj().
set("title", appPushParam.getTitle()).
set("body", appPushParam.getMessage()));
// 通知提示声音或警告通知
ios.set("sound", "default");
// 应用角标
ios.set("badge", "0");
// ios额外参数
JSONObject ios_extras = new JSONObject();
if (extras != null && extras.size() > 0) {
for (Map.Entry<String, String> m : extras.entrySet()) {
ios_extras.set(m.getKey(), m.getValue());
}
// ios额外参数
ios.set("extras", ios_extras);
}
notification.set("ios", ios);
}
}
private static void buildAndroidInfo(JSONObject notification, Map<String, String> extras,
List<PlatFormEnum> platformList, AppPushParam appPushParam) {
if (platformList != null && platformList.size() > 0 && platformList.contains(PlatFormEnum.ANDROID)) {
JSONObject android = new JSONObject();
android.set("alert", appPushParam.getMessage());
android.set("title", appPushParam.getTitle());
// 设置通知栏样式
android.set("builder_id", 1);
// android额外参数
JSONObject android_extras = new JSONObject();
if (extras != null && extras.size() > 0) {
for (Map.Entry<String, String> m : extras.entrySet()) {
android_extras.set(m.getKey(), m.getValue());
}
}
// android额外参数
android.set("extras", android_extras);
notification.set("android", android);
}
}
private static JSONObject buildCustomMessageAndroidInfo(Map<String, String> extras,
List<PlatFormEnum> platformList,
AppPushParamCustom appPushParamCustom) {
JSONObject customMessage = new JSONObject();
if (platformList != null && platformList.size() > 0 && platformList.contains(PlatFormEnum.ANDROID)) {
customMessage.set("msg_content", appPushParamCustom.getMessage());
customMessage.set("content_type", appPushParamCustom.getContentType());
customMessage.set("title", appPushParamCustom.getTitle());
// android额外参数
JSONObject extrasJson = new JSONObject();
if (extras != null && extras.size() > 0) {
for (Map.Entry<String, String> m : extras.entrySet()) {
extrasJson.set(m.getKey(), m.getValue());
}
}
customMessage.set("extras", extrasJson);
}
return customMessage;
}
/* 构建推送目标 */
private static JSONObject buildAudience(Map<String, String[]> audienceMap, JSONObject audience) {
if (audienceMap == null || audienceMap.size() == 0) {
return null;
}
for (Map.Entry<String, String[]> m : audienceMap.entrySet()) {
String[] value = m.getValue();
// 平台
JSONArray audienceArray = new JSONArray();
for (String str : value) {
audienceArray.add(str);
}
audience.set(m.getKey(), audienceArray);
}
return audience;
}
/**构建推送平台 */
private static JSONArray buildPlatform(List<PlatFormEnum> platformList, JSONArray platform) {
if (platformList != null && platformList.size() > 0) {
for (PlatFormEnum platFormEnum : platformList) {
String platformStr = platFormEnum.toString().toLowerCase();
platform.add(platformStr);
}
return platform;
} else {
return null;
}
}
}
3.11 其他 - 定义消息推送平台枚举
public enum PlatFormEnum {
ANDROID, IOS;
}
四、功能测试验证
4.1 测试第一种:通知消息
输出的log 省略,此处选择的是API
NotificationMessage{
notificationId=516752241,
msgId='18100617394282282',
appkey='appkey',
notificationContent='我是XXXX项目的推送content',
notificationAlertType=-1,
notificationTitle='我是XXXX项目的推送title',
notificationSmallIcon='',
notificationLargeIcon='',
notificationExtras='{"action":"other msg"}',
notificationStyle=0,
notificationBuilderId=1,
notificationBigText='',
notificationBigPicPath='',
notificationInbox='',
notificationPriority=0,
notificationCategory='',
developerArg0='',
platform=0,
notificationChannelId='',
displayForeground='',
notificationType=0',
inAppMsgType=1',
inAppMsgShowType=2',
inAppMsgShowPos=0',
inAppMsgTitle=,
inAppMsgContentBody=,
inAppType=0
}
4.2 测试第二种:自定义消息
输出的log 省略,此处选择的是API