
小米即时消息云IM,uni-APP 的sdk demo中 安卓端报错,网络断开问题解决
小米 免费 即时通讯IM 功能 ,官方没有提供 uniapp 或微信小程序的sdk。
下方有“开发者修改的支持微信小程序的JS库”,有大神开发者修改的支持uniapp的sdk,是用WebJS SDK改来的
之前在11.11号前 app 需要修改成 "usingComponents" : false, 打包APP后,测试是可以用的,
但由于dcloud官方 已不支持 非自定义组件模式 ,
目前打包app后,测试发现 安卓端不稳定,消息发不出去,无法登录,报错,掉线等问题。
- 使用此“小米即时消息云 MIMC uni-app SDK”,sdk开发的APP,在11月份以前"usingComponents" : false,是可以正常使用的,
但11号 uniapp 取消非自定义组件模式的编译,安卓端目前会报错,发消息不稳定,连接断开等问题。
废话不多说,解决办法: https://ext.dcloud.net.cn/plugin?id=647,
引用此js插件即可解决,。
main.js 中在引用 mimc框架前 下如下代码
import socket from '@/js_sdk/plus-websocket/index.js';
// #ifdef APP-PLUS
Object.assign(uni, socket)
// #endif
即可解决安卓端不稳定,报错等问题,
经测试收发消息已正常,无报错。
小米 免费 即时通讯IM 功能 ,官方没有提供 uniapp 或微信小程序的sdk。
下方有“开发者修改的支持微信小程序的JS库”,有大神开发者修改的支持uniapp的sdk,是用WebJS SDK改来的
之前在11.11号前 app 需要修改成 "usingComponents" : false, 打包APP后,测试是可以用的,
但由于dcloud官方 已不支持 非自定义组件模式 ,
目前打包app后,测试发现 安卓端不稳定,消息发不出去,无法登录,报错,掉线等问题。
- 使用此“小米即时消息云 MIMC uni-app SDK”,sdk开发的APP,在11月份以前"usingComponents" : false,是可以正常使用的,
但11号 uniapp 取消非自定义组件模式的编译,安卓端目前会报错,发消息不稳定,连接断开等问题。
废话不多说,解决办法: https://ext.dcloud.net.cn/plugin?id=647,
引用此js插件即可解决,。
main.js 中在引用 mimc框架前 下如下代码
import socket from '@/js_sdk/plus-websocket/index.js';
// #ifdef APP-PLUS
Object.assign(uni, socket)
// #endif
即可解决安卓端不稳定,报错等问题,
经测试收发消息已正常,无报错。

5+App使用UniPush发送消息,App在线、离线均能收到消息推送,并在通知栏进行提醒,苹果、华为、小米手机均测试通过
【1】本文档中使用的全是逶传消息,没有使用个推的其他消息
【2】需要开通UniPush功能,并在华为、小米开发者中添加App,并开通Push权限,目前不需要上架各厂商应用市场就可以使用,后续不知道需要不需要
【3】本实例使用Java后台开发,其他语言请自行翻译
【5】关于receive事件,只有发送的是透传数据【而且】不是标准格式【而且】当前应用在活动,这3个条件同时满足,才可以响应receive事件!!!,但是消息中心并没有消息展示!!!需要创建本地消息!!!才能在消息中心提醒,对于IOS的,一定要控制死循环!!!【重要】【重要】【重要】
只有APP在线时,才会触发receive事件,透传消息不会触发系统消息,需要创建本地消息【重要】【重要】【重要】
【6】关于click事件,click一定是点击通知栏的消息,才能触发!!! 下面两句话很重要
【APP在线】,收到透传消息通过,不会提醒至通知栏目,需要发送本地消息,再进行点击触发的点击事件。
【APP离线】,收到离线透传消息,必须通过Java后台的Intent字符串携带payload,且符合格式才能触发click事件,格式不符合不会触发。
【7】厂商推送需要设置的Intent字符串格式,请将${packageName},${title},${content},${payload}替换为正确的内容
${packageName} 代表应用包名
${title} 通知的标题
${content} 通知的内容
${payload} 其他附加参数,请用 JSON.toJSONString(payload)进行转码。
intent:#Intent;launchFlags=0x04000000;action=android.intent.action.oppopush;package=${packageName};component=${packageName}/io.dcloud.PandoraEntry;S.UP-OL-SU=true;S.title=${title};S.content=${content};S.payload=${payload};end
【8】APP端的javaScript代码,不需要必须写在第一个页面,我的项目写在了里面的页面,只要App启动后能打开这个页面就可以:
//收到透传消息
//只有APP在线时,才会触发receive事件,透传消息不会触发系统消息,需要创建本地消息
plus.push.addEventListener("receive", function(msg) {
console.log("(receive):" + JSON.stringify(msg));
if (app.isIOS()) { //如果是IOS
var payload = msg.payload;
//【APP离线】收到消息,但没有提醒(发生在一次收到多个离线消息时,只有一个有提醒,但其他的没有提醒)
//【APP在线】收到消息,不会触发系统消息,需要创建本地消息,但不能重复创建。必须加msg.type验证去除死循环
if (msg.aps == null && msg.type == "receive") {
var messageTitle = payload.messageTitle;
var messageContent = payload.messageContent;
//创建本地消息,发送的本地消息也会被receive方法接收到,但没有type属性,且aps是null
plus.push.createMessage(messageContent, JSON.stringify(payload), {title: messageTitle});
}
}
if (app.isAndroid()) { //如果是Android,当APP在线时,收到透传消息不会进入系统消息,需要发送本地提醒。
var payload = JSON.parse(msg.payload);
var messageTitle = payload.messageTitle;
var messageContent = payload.messageContent;
plus.push.createMessage(messageContent, msg.payload, {title: messageTitle});
}
}, false);
//消息点击事件
//【APP在线】,收到透传消息通过,不会提醒至通知栏目,需要发送本地消息,再进行点击触发的点击事件。
//【APP离线】,收到离线透传消息,必须通过Java后台的Intent字符串携带payload,且符合格式才能触发click事件,格式不符合不会触发。
plus.push.addEventListener("click", function(msg) {
console.log("(click):" + JSON.stringify(msg));
if (app.isIOS()) { //如果是IOS
var payload;
if (msg.type == "click") { //APP离线点击包含click属性,这时payload是JSON对象
payload = msg.payload;
} else { //APP在线,收到消息不会包含type属性,这时的payload是JSON字符串,需要转为JSON对象
payload = JSON.parse(msg.payload);
}
if (payload != null || payload != undefined) {
var messageType = payload.messageType;
messageClick(messageType, payload);
}
}
if (app.isAndroid()) { //如果是Android,收到playload均是是JSON字符串,需要转为JSON对象
var payload = JSON.parse(msg.payload);
if (payload != null || payload != undefined) {
var messageType = payload.messageType;
messageClick(messageType, payload);
}
}
}, false);
【9】java后台发送代码 ,代码中注释的内容,本人没有研究明白,未进行测试。
/**
* 推送消息至App所有用户,100次/天,每分钟不能超过5次,相同的消息内容,10分钟内不可以重复发送<br/>
* 华为,平果测试通过
*
* @param getuiMessage
* @return
*/
public static IPushResult toApp(GetuiMessage getuiMessage) {
TransmissionTemplate template = PushTemplate.getTransmissionTemplateWith3rdNotifyInfoAndAPNPayload(getuiMessage.getMessageTitle(),
getuiMessage.getMessageContent(), "+1", getuiMessage);
AppMessage message = new AppMessage();
message.setData(template);
message.setOffline(true);
message.setOfflineExpireTime(24 * 1000 * 3600);
message.setAppIdList(Arrays.asList(GetuiConfig.me.getAppId()));
IPushResult ret = GetuiConfig.me.getPush().pushMessageToApp(message);
GetuiConfig.logger.info(GetuiConfig.logger.getName() + JSON.toJSONString(ret));
return ret;
}
/**
* 推送消息至特定的ClientID,频次限制:没有限制!
*
* @param getuiMessage 消息对象
* @param clientId 接收的ClientId
* @return
*/
public static IPushResult toSingle(GetuiMessage getuiMessage, String clientId) {
// 获取消息模板
TransmissionTemplate template = PushTemplate.getTransmissionTemplateWith3rdNotifyInfoAndAPNPayload(getuiMessage.getMessageTitle(),
getuiMessage.getMessageContent(), "+1", getuiMessage);
// 制作消息
SingleMessage message = new SingleMessage();
message.setData(template);
message.setOffline(true);// 设置消息离线,并设置离线时间
message.setOfflineExpireTime(72 * 3600 * 1000); // 离线有效时间,单位为毫秒,可选
// message.setPriority(1);// 优先级
// message.setPushNetWorkType(0); // 判断客户端是否wifi环境下推送。1为仅在wifi环境下推送,0为不限制网络环境,默认不限
// 生成接收人
Target target = new Target();
target.setAppId(GetuiConfig.me.getAppId());
target.setClientId(clientId);
// 发送消息
IPushResult ret = GetuiConfig.me.getPush().pushMessageToSingle(message, target);
GetuiConfig.logger.info(GetuiConfig.logger.getName() + JSON.toJSONString(ret));
return ret;
}
/**
* 获取同时有Android第三方推送及IOS推送功能的很透传消息
*
* @param title 标题
* @param body 正文
* @param badge IOS的角标数
* @param customParam 自定义属性
* @return
*/
public static TransmissionTemplate getTransmissionTemplateWith3rdNotifyInfoAndAPNPayload(String title, String body, String badge,
Map<String, String> customParam) {
TransmissionTemplate template = new TransmissionTemplate();
// 设置APPID与APPKEY
template.setAppId(GetuiConfig.me.getAppId());
template.setAppkey(GetuiConfig.me.getAppKey());
// 透传消息设置,1为强制启动应用,客户端接收到消息后就会立即启动应用;2为等待应用启动
template.setTransmissionType(2);
template.setTransmissionContent(JSON.toJSONString(customParam)); // 透传内容
// 第三方厂商推送
template.set3rdNotifyInfo(get3rdNotifyInfo(title, body, customParam));
// 针对IOS,设置APNs
template.setAPNInfo(getAPNPayload(title, body, badge, customParam)); // ios消息推送
return template;
}
/**
* 第三方厂商通知
*
* @param title 标题
* @param content 正文
* @param payload 附带属性
* @return
*/
private static Notify get3rdNotifyInfo(String title, String content, Map<String, String> payload) {
Notify notify = new Notify();
notify.setTitle(title);
notify.setContent(content);
notify.setType(Type._intent);
notify.setIntent(GetuiConfig.me.getIntent(title,content,payload));
notify.setPayload(JSON.toJSONString(payload));
return notify;
}
/**
* IOS的APNs消息
*
* @param title
* @param body
* @param badge
* @param customMsg
* @return
*/
private static APNPayload getAPNPayload(String title, String body, String badge, Map<String, String> customMsg) {
APNPayload payload = new APNPayload();
// 在已有数字基础上加1显示,设置为-1时,在已有数字上减1显示,设置为数字时,显示指定数字
if (badge != null && badge.trim().length() > 0) {
payload.setAutoBadge(badge);
}
payload.setContentAvailable(1);
// ios 12.0 以上可以使用 Dictionary 类型的 sound
payload.setSound("default");
// payload.setCategory("$由客户端定义");
if (customMsg != null) {
for (Entry<String, String> enty : customMsg.entrySet()) {
payload.addCustomMsg(enty.getKey(), enty.getValue());
}
}
// payload.setAlertMsg(new APNPayload.SimpleAlertMsg("helloCCCC"));//简单模式APNPayload.SimpleMsg
payload.setAlertMsg(getDictionaryAlertMsg(title, body)); // 字典模式使用APNPayload.DictionaryAlertMsg
// // 设置语音播报类型,int类型,0.不可用 1.播放body 2.播放自定义文本
// payload.setVoicePlayType(2);
// // 设置语音播报内容,String类型,非必须参数,用户自定义播放内容,仅在voicePlayMessage=2时生效
// // 注:当"定义类型"=2, "定义内容"为空时则忽略不播放
// payload.setVoicePlayMessage("定义内容");
//
// // 添加多媒体资源
// payload.addMultiMedia(new MultiMedia().setResType(MultiMedia.MediaType.pic).setResUrl("资源文件地址").setOnlyWifi(true));
return payload;
}
/**
* IOS通知提示样式
*
* @param title
* @param body
* @return
*/
private static APNPayload.DictionaryAlertMsg getDictionaryAlertMsg(String title, String body) {
APNPayload.DictionaryAlertMsg alertMsg = new APNPayload.DictionaryAlertMsg();
alertMsg.setBody(body);
// alertMsg.setActionLocKey("显示关闭和查看两个按钮的消息");
// alertMsg.setLocKey("loc-key1");
// alertMsg.addLocArg("loc-ary1");
// alertMsg.setLaunchImage("调用已经在应用程序中绑定的图形文件名");
// iOS8.2以上版本支持
alertMsg.setTitle(title);
// alertMsg.setTitleLocKey("自定义通知标题");
// alertMsg.addTitleLocArg("自定义通知标题组");
return alertMsg;
}
/**
* 需要使用iOS语音传输,请使用VoIPPayload代替APNPayload【未测试】
*
*
* @return
*/
private static VoIPPayload getVoIPPayload() {
//TODO 未测试,未开发完成
VoIPPayload payload = new VoIPPayload();
JSONObject jo = new JSONObject();
jo.put("key1", "value1");
payload.setVoIPPayload(jo.toString());
return payload;
}
public class GetuiMessage extends HashMap<String, String> {
/**
*
*/
private static final long serialVersionUID = -5993986890576211345L;
private final String messageTitle = "messageTitle";
private final String messageContent = "messageContent";
private final String messageType = "messageType";
/**
* 生成推送消息
*
* @param typeEnum 消息类型
* @param customParam 消息内容参数和消息点击需要的参加共享相同参数
*/
public GetuiMessage(MessageType typeEnum, Map<String, String> customParam) {
if (customParam != null && customParam.size() > 0) {
this.putAll(customParam);
}
// 把优先级高的Key放在后面,即遍在customParam有重复的KEY,也不会影响。
this.put(messageTitle, typeEnum.getTitle());
this.put(messageType, typeEnum.getCode());
this.put(messageContent, typeEnum.getContent(customParam));
}
参考(Push推送使用指南):https://ask.dcloud.net.cn/article/35622
【1】本文档中使用的全是逶传消息,没有使用个推的其他消息
【2】需要开通UniPush功能,并在华为、小米开发者中添加App,并开通Push权限,目前不需要上架各厂商应用市场就可以使用,后续不知道需要不需要
【3】本实例使用Java后台开发,其他语言请自行翻译
【5】关于receive事件,只有发送的是透传数据【而且】不是标准格式【而且】当前应用在活动,这3个条件同时满足,才可以响应receive事件!!!,但是消息中心并没有消息展示!!!需要创建本地消息!!!才能在消息中心提醒,对于IOS的,一定要控制死循环!!!【重要】【重要】【重要】
只有APP在线时,才会触发receive事件,透传消息不会触发系统消息,需要创建本地消息【重要】【重要】【重要】
【6】关于click事件,click一定是点击通知栏的消息,才能触发!!! 下面两句话很重要
【APP在线】,收到透传消息通过,不会提醒至通知栏目,需要发送本地消息,再进行点击触发的点击事件。
【APP离线】,收到离线透传消息,必须通过Java后台的Intent字符串携带payload,且符合格式才能触发click事件,格式不符合不会触发。
【7】厂商推送需要设置的Intent字符串格式,请将${packageName},${title},${content},${payload}替换为正确的内容
${packageName} 代表应用包名
${title} 通知的标题
${content} 通知的内容
${payload} 其他附加参数,请用 JSON.toJSONString(payload)进行转码。
intent:#Intent;launchFlags=0x04000000;action=android.intent.action.oppopush;package=${packageName};component=${packageName}/io.dcloud.PandoraEntry;S.UP-OL-SU=true;S.title=${title};S.content=${content};S.payload=${payload};end
【8】APP端的javaScript代码,不需要必须写在第一个页面,我的项目写在了里面的页面,只要App启动后能打开这个页面就可以:
//收到透传消息
//只有APP在线时,才会触发receive事件,透传消息不会触发系统消息,需要创建本地消息
plus.push.addEventListener("receive", function(msg) {
console.log("(receive):" + JSON.stringify(msg));
if (app.isIOS()) { //如果是IOS
var payload = msg.payload;
//【APP离线】收到消息,但没有提醒(发生在一次收到多个离线消息时,只有一个有提醒,但其他的没有提醒)
//【APP在线】收到消息,不会触发系统消息,需要创建本地消息,但不能重复创建。必须加msg.type验证去除死循环
if (msg.aps == null && msg.type == "receive") {
var messageTitle = payload.messageTitle;
var messageContent = payload.messageContent;
//创建本地消息,发送的本地消息也会被receive方法接收到,但没有type属性,且aps是null
plus.push.createMessage(messageContent, JSON.stringify(payload), {title: messageTitle});
}
}
if (app.isAndroid()) { //如果是Android,当APP在线时,收到透传消息不会进入系统消息,需要发送本地提醒。
var payload = JSON.parse(msg.payload);
var messageTitle = payload.messageTitle;
var messageContent = payload.messageContent;
plus.push.createMessage(messageContent, msg.payload, {title: messageTitle});
}
}, false);
//消息点击事件
//【APP在线】,收到透传消息通过,不会提醒至通知栏目,需要发送本地消息,再进行点击触发的点击事件。
//【APP离线】,收到离线透传消息,必须通过Java后台的Intent字符串携带payload,且符合格式才能触发click事件,格式不符合不会触发。
plus.push.addEventListener("click", function(msg) {
console.log("(click):" + JSON.stringify(msg));
if (app.isIOS()) { //如果是IOS
var payload;
if (msg.type == "click") { //APP离线点击包含click属性,这时payload是JSON对象
payload = msg.payload;
} else { //APP在线,收到消息不会包含type属性,这时的payload是JSON字符串,需要转为JSON对象
payload = JSON.parse(msg.payload);
}
if (payload != null || payload != undefined) {
var messageType = payload.messageType;
messageClick(messageType, payload);
}
}
if (app.isAndroid()) { //如果是Android,收到playload均是是JSON字符串,需要转为JSON对象
var payload = JSON.parse(msg.payload);
if (payload != null || payload != undefined) {
var messageType = payload.messageType;
messageClick(messageType, payload);
}
}
}, false);
【9】java后台发送代码 ,代码中注释的内容,本人没有研究明白,未进行测试。
/**
* 推送消息至App所有用户,100次/天,每分钟不能超过5次,相同的消息内容,10分钟内不可以重复发送<br/>
* 华为,平果测试通过
*
* @param getuiMessage
* @return
*/
public static IPushResult toApp(GetuiMessage getuiMessage) {
TransmissionTemplate template = PushTemplate.getTransmissionTemplateWith3rdNotifyInfoAndAPNPayload(getuiMessage.getMessageTitle(),
getuiMessage.getMessageContent(), "+1", getuiMessage);
AppMessage message = new AppMessage();
message.setData(template);
message.setOffline(true);
message.setOfflineExpireTime(24 * 1000 * 3600);
message.setAppIdList(Arrays.asList(GetuiConfig.me.getAppId()));
IPushResult ret = GetuiConfig.me.getPush().pushMessageToApp(message);
GetuiConfig.logger.info(GetuiConfig.logger.getName() + JSON.toJSONString(ret));
return ret;
}
/**
* 推送消息至特定的ClientID,频次限制:没有限制!
*
* @param getuiMessage 消息对象
* @param clientId 接收的ClientId
* @return
*/
public static IPushResult toSingle(GetuiMessage getuiMessage, String clientId) {
// 获取消息模板
TransmissionTemplate template = PushTemplate.getTransmissionTemplateWith3rdNotifyInfoAndAPNPayload(getuiMessage.getMessageTitle(),
getuiMessage.getMessageContent(), "+1", getuiMessage);
// 制作消息
SingleMessage message = new SingleMessage();
message.setData(template);
message.setOffline(true);// 设置消息离线,并设置离线时间
message.setOfflineExpireTime(72 * 3600 * 1000); // 离线有效时间,单位为毫秒,可选
// message.setPriority(1);// 优先级
// message.setPushNetWorkType(0); // 判断客户端是否wifi环境下推送。1为仅在wifi环境下推送,0为不限制网络环境,默认不限
// 生成接收人
Target target = new Target();
target.setAppId(GetuiConfig.me.getAppId());
target.setClientId(clientId);
// 发送消息
IPushResult ret = GetuiConfig.me.getPush().pushMessageToSingle(message, target);
GetuiConfig.logger.info(GetuiConfig.logger.getName() + JSON.toJSONString(ret));
return ret;
}
/**
* 获取同时有Android第三方推送及IOS推送功能的很透传消息
*
* @param title 标题
* @param body 正文
* @param badge IOS的角标数
* @param customParam 自定义属性
* @return
*/
public static TransmissionTemplate getTransmissionTemplateWith3rdNotifyInfoAndAPNPayload(String title, String body, String badge,
Map<String, String> customParam) {
TransmissionTemplate template = new TransmissionTemplate();
// 设置APPID与APPKEY
template.setAppId(GetuiConfig.me.getAppId());
template.setAppkey(GetuiConfig.me.getAppKey());
// 透传消息设置,1为强制启动应用,客户端接收到消息后就会立即启动应用;2为等待应用启动
template.setTransmissionType(2);
template.setTransmissionContent(JSON.toJSONString(customParam)); // 透传内容
// 第三方厂商推送
template.set3rdNotifyInfo(get3rdNotifyInfo(title, body, customParam));
// 针对IOS,设置APNs
template.setAPNInfo(getAPNPayload(title, body, badge, customParam)); // ios消息推送
return template;
}
/**
* 第三方厂商通知
*
* @param title 标题
* @param content 正文
* @param payload 附带属性
* @return
*/
private static Notify get3rdNotifyInfo(String title, String content, Map<String, String> payload) {
Notify notify = new Notify();
notify.setTitle(title);
notify.setContent(content);
notify.setType(Type._intent);
notify.setIntent(GetuiConfig.me.getIntent(title,content,payload));
notify.setPayload(JSON.toJSONString(payload));
return notify;
}
/**
* IOS的APNs消息
*
* @param title
* @param body
* @param badge
* @param customMsg
* @return
*/
private static APNPayload getAPNPayload(String title, String body, String badge, Map<String, String> customMsg) {
APNPayload payload = new APNPayload();
// 在已有数字基础上加1显示,设置为-1时,在已有数字上减1显示,设置为数字时,显示指定数字
if (badge != null && badge.trim().length() > 0) {
payload.setAutoBadge(badge);
}
payload.setContentAvailable(1);
// ios 12.0 以上可以使用 Dictionary 类型的 sound
payload.setSound("default");
// payload.setCategory("$由客户端定义");
if (customMsg != null) {
for (Entry<String, String> enty : customMsg.entrySet()) {
payload.addCustomMsg(enty.getKey(), enty.getValue());
}
}
// payload.setAlertMsg(new APNPayload.SimpleAlertMsg("helloCCCC"));//简单模式APNPayload.SimpleMsg
payload.setAlertMsg(getDictionaryAlertMsg(title, body)); // 字典模式使用APNPayload.DictionaryAlertMsg
// // 设置语音播报类型,int类型,0.不可用 1.播放body 2.播放自定义文本
// payload.setVoicePlayType(2);
// // 设置语音播报内容,String类型,非必须参数,用户自定义播放内容,仅在voicePlayMessage=2时生效
// // 注:当"定义类型"=2, "定义内容"为空时则忽略不播放
// payload.setVoicePlayMessage("定义内容");
//
// // 添加多媒体资源
// payload.addMultiMedia(new MultiMedia().setResType(MultiMedia.MediaType.pic).setResUrl("资源文件地址").setOnlyWifi(true));
return payload;
}
/**
* IOS通知提示样式
*
* @param title
* @param body
* @return
*/
private static APNPayload.DictionaryAlertMsg getDictionaryAlertMsg(String title, String body) {
APNPayload.DictionaryAlertMsg alertMsg = new APNPayload.DictionaryAlertMsg();
alertMsg.setBody(body);
// alertMsg.setActionLocKey("显示关闭和查看两个按钮的消息");
// alertMsg.setLocKey("loc-key1");
// alertMsg.addLocArg("loc-ary1");
// alertMsg.setLaunchImage("调用已经在应用程序中绑定的图形文件名");
// iOS8.2以上版本支持
alertMsg.setTitle(title);
// alertMsg.setTitleLocKey("自定义通知标题");
// alertMsg.addTitleLocArg("自定义通知标题组");
return alertMsg;
}
/**
* 需要使用iOS语音传输,请使用VoIPPayload代替APNPayload【未测试】
*
*
* @return
*/
private static VoIPPayload getVoIPPayload() {
//TODO 未测试,未开发完成
VoIPPayload payload = new VoIPPayload();
JSONObject jo = new JSONObject();
jo.put("key1", "value1");
payload.setVoIPPayload(jo.toString());
return payload;
}
public class GetuiMessage extends HashMap<String, String> {
/**
*
*/
private static final long serialVersionUID = -5993986890576211345L;
private final String messageTitle = "messageTitle";
private final String messageContent = "messageContent";
private final String messageType = "messageType";
/**
* 生成推送消息
*
* @param typeEnum 消息类型
* @param customParam 消息内容参数和消息点击需要的参加共享相同参数
*/
public GetuiMessage(MessageType typeEnum, Map<String, String> customParam) {
if (customParam != null && customParam.size() > 0) {
this.putAll(customParam);
}
// 把优先级高的Key放在后面,即遍在customParam有重复的KEY,也不会影响。
this.put(messageTitle, typeEnum.getTitle());
this.put(messageType, typeEnum.getCode());
this.put(messageContent, typeEnum.getContent(customParam));
}
参考(Push推送使用指南):https://ask.dcloud.net.cn/article/35622
收起阅读 »
找人用Uni-app开发小程序及APP
我现在有个小程序需要用uin-app开发,后端及接口都已经写好,后端是JAVA 有时间做的联系我Q Q3013321536
我现在有个小程序需要用uin-app开发,后端及接口都已经写好,后端是JAVA 有时间做的联系我Q Q3013321536

h5+开发的app内容秒加载的方法
在由列表页进入详情页时,如果在打开详情页再去请求详情数据的话,除非你服务器配置带宽喜人,不然一般都会有一点延迟加载的感觉
怎样才能打开就秒开呢?其实做法就是提前缓存数据
比如,在打开app时有个启动动画,在加载启动动画页时就缓存需要的数据,比如文章标题、内容
原来我想通过mui预加载的形式看能不能先运行缓存页,结果证明是行不通的
没办法,只能用ajax先运行缓存页,由缓存页把数据先缓存好
比如定义hc.html 为缓存页面,那么在hc.html这个页面就去请求你服务器的数据,载入进来后存入客户端本地
这样从启动页进入首页后,你需要的数据也都载入进来了,一进页面就用缓存数据替换dom内容,而且这个数据都是最新的
当然你也可以在页面上拉新,如果是新数据就替换原来的缓存即可
在由列表页进入详情页时,如果在打开详情页再去请求详情数据的话,除非你服务器配置带宽喜人,不然一般都会有一点延迟加载的感觉
怎样才能打开就秒开呢?其实做法就是提前缓存数据
比如,在打开app时有个启动动画,在加载启动动画页时就缓存需要的数据,比如文章标题、内容
原来我想通过mui预加载的形式看能不能先运行缓存页,结果证明是行不通的
没办法,只能用ajax先运行缓存页,由缓存页把数据先缓存好
比如定义hc.html 为缓存页面,那么在hc.html这个页面就去请求你服务器的数据,载入进来后存入客户端本地
这样从启动页进入首页后,你需要的数据也都载入进来了,一进页面就用缓存数据替换dom内容,而且这个数据都是最新的
当然你也可以在页面上拉新,如果是新数据就替换原来的缓存即可

当你使用wap2app终于成功打包 完美上线的时候....你却哭了
为什么哭了呢,不会写代码,用强大的wap2app封装了一个,哪哪都满意,却突然跳出一个弹框 出现提示 无法连接服务器,请检查网络设置。稍微几张图片都是经常出现.....至此,极大影响体验,整个付出的心血就此报废,真是可惜了强大的wap2app,官方截止目前并没有解决此问题,所以,做之前慎重考虑,不然....
附报BUG的链接:https://ask.dcloud.net.cn/question/73941 确认你能接受在考虑封装吧
为什么哭了呢,不会写代码,用强大的wap2app封装了一个,哪哪都满意,却突然跳出一个弹框 出现提示 无法连接服务器,请检查网络设置。稍微几张图片都是经常出现.....至此,极大影响体验,整个付出的心血就此报废,真是可惜了强大的wap2app,官方截止目前并没有解决此问题,所以,做之前慎重考虑,不然....
附报BUG的链接:https://ask.dcloud.net.cn/question/73941 确认你能接受在考虑封装吧
收起阅读 »
uni-app 使用高斯模糊/毛玻璃效果
此文档不再维护,请参考新文档地址:https://uniapp.dcloud.io/tutorial/app-blureffect
TabBar 使用高斯模糊效果
<a id="tabbar"></a>
HBuilderX 从 2.4.4 版本开始,uni-app iOS 端 TabBar 支持高斯模糊效果(毛玻璃效果)。
HBuilderX 从 3.4.10 版本开始,uni-app Android 端 TabBar 支持高斯模糊效果(毛玻璃效果)。
下面介绍一下如何使用高斯模糊效果,和一些注意事项。
效果

示例 demo 地址 https://github.com/dcloudio/BlurEffectDemo (点进去了,记得 star 一波)
实现原理
实现原理很简单,启用高斯模糊效果后,页面会变高(增加 tabBar 的高度),页面布局会延伸到 tabBar 下面,框架会在 tabBar 上自动添加一个高斯模糊效果的视图,然后透过这个视图看下面的内容就会看到模糊的效果。
使用高斯模糊效果需要注意:
- 启用高斯模糊效果后,不建议设置 tabBar 的 backgroundColor,如果非要设置的话需要使用
rgba
设置透明度,否则看不到模糊效果; - 由于页面高度发生了变化,因此在页面布局上需要有一些注意事项(很简单),下面会说明
vue
及nvue
页面如何适配;并会提供一个 demo,供大家参考; - 启用高斯模糊效果后不要动态设置 tabBar 的隐藏,不然会影响页面布局;
-
为了方便开发者适配多平台,框架已经提供了获取 tabBar 高度的方法,并会根据不同平台返回不同的值
windowBottom
;使用方法如下// vue中直接在 css 中使用 .fixed1{ position: fixed; left: 0; bottom: var(--window-bottom); } // nvue 不支持css的写法,请使用 js 方法 获取 uni.getSystemInfoSync().windowBottom
启用高斯模糊效果
首先需要在 manifest.json
的 app-plus
节点下添加 safearea
的配置,bottom
的 offset
设置为 none
,这样平台会自动处理 iPhoneX 等全面屏机型的高度适配,不然在全面屏机型上可能会出现页面被遮挡的问题
// manifest.json
"app-plus": {
...
"safearea" : {
"bottom" : {
"offset" : "none"
}
}
...
}
然后在 pages.json
中添加 tabBar
的配置信息,并配置 blurEffect
值
{
...
...
"tabBar": {
"blurEffect":"extralight",
"color": "#999999",
"borderStyle": "#000000",
// 注意:启用高斯模糊效果后不建议设置backgroundColor,如果需要设置的需要使用 rgba 设置透明度,不然看不到模糊效果
// "backgroundColor": "rgba(0,255,51,0.3)",
"spacing": "5px",
"height": "50px",
"selectedColor": "#0062cc",
"list": [
{
"text" : "HELLO",
"iconPath" : "static/ic_tabbar_home_nor.png",
"selectedIconPath" : "static/ic_tabbar_home_sel.png",
"pagePath": "pages/index/index"
},
{
"text" : "WORLD",
"iconPath" : "static/ic_tabbar_group_nor.png",
"selectedIconPath" : "static/ic_tabbar_group_sel.png",
"pagePath": "pages/index/page"
}]
}
}
blurEffect 对应的就是高斯模糊的配置,可取值:
- "dark" - 暗风格模糊,对应iOS原生UIBlurEffectStyleDark效果;
- "extralight" - 高亮风格模糊,对应iOS原生UIBlurEffectStyleExtraLight效果;
- "light" - 亮风格模糊,对应iOS原生UIBlurEffectStyleLight效果;
- "none" - 无模糊效果。
vue 页面适配
- 添加占位视图:由于页面高度变高了,页面会被 tabBar 挡住,所以需要在页面最下面添加一个占位视图,高度设置为 tabBar 的高度,这样页面的元素就不会被 tabBar 挡住了(启用高斯模糊效果,框架会自动处理滚动条底部的偏移不会被tabBar遮挡);
- 绝对定位注意事项:同样因为页面高度变化了,绝对定位的视图需要考虑 tabBar 的遮挡问题,例如想要一个 view 固定在页面最底部,需要设置 bottom 值为 tabBar 的高度即可;
示例(源码请参考示例工程的 index.vue)
<template>
<view class="content">
<image v-for="index in 3" :key='index' src="../../static/test.png" style="width: 750rpx; height: 1136rpx;" mode="scaleToFill"></image>
<!-- 在页面最下方添加占位视图,高度等于 tabBar 的高度 -->
<view class="edgeInsetBottom"></view>
<!-- 绝对定位的视图需要考虑 tabBar 遮挡的问题,bottom 应该加上 tabBar 的高度 -->
<view class="fixedView"></view>
</view>
</template>
<script>
export default {
data() {
return {
tabbarHeight:0
}
},
onReady() {
// 获取 tabBar 的高度
this.tabbarHeight = uni.getSystemInfoSync().windowBottom;
}
}
</script>
<style>
.content {
background-color: #FFFFFF;
line-height: 0;
}
.edgeInsetBottom {
width: 750rpx;
height: var(--window-bottom);
background-color: #FFFFFF;
}
.fixedView{
position: fixed;
width: 750rpx;
height: 30px;
background-color: #4CD964;
bottom: var(--window-bottom);
}
</style>
nvue 页面适配
因为 nvue 页面为纯原生布局,当启用毛玻璃效果后,原生端框架可以自动调整滚动视图的 contentInset bottom 值,相当于在页面最底部,偏移出 tabbar 的高度,这样页面原有的元素就不会被遮挡,滚动条的位置也会自动处理。注:偏移出的位置显示的是滚动视图的背影颜色;
- 滚动视图添加 adjustBottom="true":只有添加了 adjustBottom="true" 框架才会自动调整滚动视图的 contentInset bottom 值,这里有一点需要注意,如果你的页面整体是滚动的,那么需要你的页面根节点为滚动视图然后添加 adjustBottom="true",如果页面部分是可以滚动的,那就在页面最下面的滚动视图添加 adjustBottom="true" 属性;(技巧就是会被 tabBar 遮挡住的滚动视图添加属性)
- 绝对定位注意事项:跟vue页面一样,绝对定位的视图需要考虑 tabBar 的遮挡问题,例如想要一个 view 固定在页面最底部,需要设置 bottom 值为 tabBar 的高度即可;
示例
<template>
<!-- 页面根节点为滚动视图,并添加 adjustBottom="true" -->
<scroll-view class="content" scroll-y="true" adjustBottom="true">
<image v-for="index in 3" :key='index' src="../../static/test.png" style="width: 750rpx; height: 1136rpx;" mode="scaleToFill"></image>
<!-- 绝对定位的视图需要考虑 tabBar 遮挡的问题,bottom 应该加上 tabBar 的高度 -->
<view class="fixedView" :style="{ bottom : tabbarHeight + 'px'}"></view>
</scroll-view>
</template>
<script>
export default {
data() {
return {
tabbarHeight: 0
}
},
onReady() {
// 获取 tabBar 的高度
this.tabbarHeight = uni.getSystemInfoSync().windowBottom;
}
}
</script>
<style>
.content {
background-color: #FFFFFF;
line-height: 0;
}
.fixedView{
position: fixed;
width: 750rpx;
height: 30px;
background-color: #4CD964;
}
</style>
<a id="view"></a>
nvue view组件使用高斯模糊效果
HBuilderX 从 2.4.8+ 版本开始,IOS 端 nvue view组件支持高斯模糊效果(毛玻璃效果)。
效果
使用方法
在 view 组件中添加 blurEffect
属性启用高斯模糊效果,取值同 TabBar
- "dark" - 暗风格模糊,对应iOS原生UIBlurEffectStyleDark效果;
- "extralight" - 高亮风格模糊,对应iOS原生UIBlurEffectStyleExtraLight效果;
- "light" - 亮风格模糊,对应iOS原生UIBlurEffectStyleLight效果;
- "none" - 无模糊效果。
注意事项
- 启用高斯模糊效果后,不建议设置 background-color,如果非要设置的话需要使用
rgba
设置透明度,否则看不到模糊效果; - 启用高斯模糊效果后相当于 view 组件对应的视图变成了毛玻璃,透过 view 看下面的内容会有模糊效果, view 上添加的视图不受影响;
示例
<template>
<view class="container">
<image src="../../static/3.jpg" class="img" mode="aspectFill"></image>
<view class="blur" blurEffect="light">
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
}
}
</script>
<style>
.container{
flex: 1;
}
.img {
flex: 1;
}
.blur{
position: fixed;
top: 300rpx;
bottom: 300rpx;
left: 20px;
right: 20px;
/* background-color: rgba(152,245,255,0.3); */
}
</style>
navigationBar 使用高斯模糊效果
HBuilderX 从 2.4.4 版本开始,uni-app iOS 端 navigationBar 支持高斯模糊效果(毛玻璃效果)。
HBuilderX 从 3.4.10 版本开始,uni-app Android 端 navigationBar 支持高斯模糊效果(毛玻璃效果)。
使用方法
页面 style --> app-plus --> titleNView中添加 blurEffect
属性启用高斯模糊效果
- "dark" - 暗风格模糊,对应iOS原生UIBlurEffectStyleDark效果;
- "extralight" - 高亮风格模糊,对应iOS原生UIBlurEffectStyleExtraLight效果;
- "light" - 亮风格模糊,对应iOS原生UIBlurEffectStyleLight效果;
- "none" - 无模糊效果。
示例
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "vue",
"app-plus":{
"bounce":"vertical",
"titleNView": {
"blurEffect":"extralight",
"backgroundColor": "#00ffffff",
"type" : "float"
}
}
}
}
}
注意:backgroundColor需要设置带有透明度颜色才能看到高斯模糊效果。不设置backgroundColor也无法看到高斯模糊效果!
此文档不再维护,请参考新文档地址:https://uniapp.dcloud.io/tutorial/app-blureffect
TabBar 使用高斯模糊效果
<a id="tabbar"></a>
HBuilderX 从 2.4.4 版本开始,uni-app iOS 端 TabBar 支持高斯模糊效果(毛玻璃效果)。
HBuilderX 从 3.4.10 版本开始,uni-app Android 端 TabBar 支持高斯模糊效果(毛玻璃效果)。
下面介绍一下如何使用高斯模糊效果,和一些注意事项。
效果
示例 demo 地址 https://github.com/dcloudio/BlurEffectDemo (点进去了,记得 star 一波)
实现原理
实现原理很简单,启用高斯模糊效果后,页面会变高(增加 tabBar 的高度),页面布局会延伸到 tabBar 下面,框架会在 tabBar 上自动添加一个高斯模糊效果的视图,然后透过这个视图看下面的内容就会看到模糊的效果。
使用高斯模糊效果需要注意:
- 启用高斯模糊效果后,不建议设置 tabBar 的 backgroundColor,如果非要设置的话需要使用
rgba
设置透明度,否则看不到模糊效果; - 由于页面高度发生了变化,因此在页面布局上需要有一些注意事项(很简单),下面会说明
vue
及nvue
页面如何适配;并会提供一个 demo,供大家参考; - 启用高斯模糊效果后不要动态设置 tabBar 的隐藏,不然会影响页面布局;
-
为了方便开发者适配多平台,框架已经提供了获取 tabBar 高度的方法,并会根据不同平台返回不同的值
windowBottom
;使用方法如下// vue中直接在 css 中使用 .fixed1{ position: fixed; left: 0; bottom: var(--window-bottom); } // nvue 不支持css的写法,请使用 js 方法 获取 uni.getSystemInfoSync().windowBottom
启用高斯模糊效果
首先需要在 manifest.json
的 app-plus
节点下添加 safearea
的配置,bottom
的 offset
设置为 none
,这样平台会自动处理 iPhoneX 等全面屏机型的高度适配,不然在全面屏机型上可能会出现页面被遮挡的问题
// manifest.json
"app-plus": {
...
"safearea" : {
"bottom" : {
"offset" : "none"
}
}
...
}
然后在 pages.json
中添加 tabBar
的配置信息,并配置 blurEffect
值
{
...
...
"tabBar": {
"blurEffect":"extralight",
"color": "#999999",
"borderStyle": "#000000",
// 注意:启用高斯模糊效果后不建议设置backgroundColor,如果需要设置的需要使用 rgba 设置透明度,不然看不到模糊效果
// "backgroundColor": "rgba(0,255,51,0.3)",
"spacing": "5px",
"height": "50px",
"selectedColor": "#0062cc",
"list": [
{
"text" : "HELLO",
"iconPath" : "static/ic_tabbar_home_nor.png",
"selectedIconPath" : "static/ic_tabbar_home_sel.png",
"pagePath": "pages/index/index"
},
{
"text" : "WORLD",
"iconPath" : "static/ic_tabbar_group_nor.png",
"selectedIconPath" : "static/ic_tabbar_group_sel.png",
"pagePath": "pages/index/page"
}]
}
}
blurEffect 对应的就是高斯模糊的配置,可取值:
- "dark" - 暗风格模糊,对应iOS原生UIBlurEffectStyleDark效果;
- "extralight" - 高亮风格模糊,对应iOS原生UIBlurEffectStyleExtraLight效果;
- "light" - 亮风格模糊,对应iOS原生UIBlurEffectStyleLight效果;
- "none" - 无模糊效果。
vue 页面适配
- 添加占位视图:由于页面高度变高了,页面会被 tabBar 挡住,所以需要在页面最下面添加一个占位视图,高度设置为 tabBar 的高度,这样页面的元素就不会被 tabBar 挡住了(启用高斯模糊效果,框架会自动处理滚动条底部的偏移不会被tabBar遮挡);
- 绝对定位注意事项:同样因为页面高度变化了,绝对定位的视图需要考虑 tabBar 的遮挡问题,例如想要一个 view 固定在页面最底部,需要设置 bottom 值为 tabBar 的高度即可;
示例(源码请参考示例工程的 index.vue)
<template>
<view class="content">
<image v-for="index in 3" :key='index' src="../../static/test.png" style="width: 750rpx; height: 1136rpx;" mode="scaleToFill"></image>
<!-- 在页面最下方添加占位视图,高度等于 tabBar 的高度 -->
<view class="edgeInsetBottom"></view>
<!-- 绝对定位的视图需要考虑 tabBar 遮挡的问题,bottom 应该加上 tabBar 的高度 -->
<view class="fixedView"></view>
</view>
</template>
<script>
export default {
data() {
return {
tabbarHeight:0
}
},
onReady() {
// 获取 tabBar 的高度
this.tabbarHeight = uni.getSystemInfoSync().windowBottom;
}
}
</script>
<style>
.content {
background-color: #FFFFFF;
line-height: 0;
}
.edgeInsetBottom {
width: 750rpx;
height: var(--window-bottom);
background-color: #FFFFFF;
}
.fixedView{
position: fixed;
width: 750rpx;
height: 30px;
background-color: #4CD964;
bottom: var(--window-bottom);
}
</style>
nvue 页面适配
因为 nvue 页面为纯原生布局,当启用毛玻璃效果后,原生端框架可以自动调整滚动视图的 contentInset bottom 值,相当于在页面最底部,偏移出 tabbar 的高度,这样页面原有的元素就不会被遮挡,滚动条的位置也会自动处理。注:偏移出的位置显示的是滚动视图的背影颜色;
- 滚动视图添加 adjustBottom="true":只有添加了 adjustBottom="true" 框架才会自动调整滚动视图的 contentInset bottom 值,这里有一点需要注意,如果你的页面整体是滚动的,那么需要你的页面根节点为滚动视图然后添加 adjustBottom="true",如果页面部分是可以滚动的,那就在页面最下面的滚动视图添加 adjustBottom="true" 属性;(技巧就是会被 tabBar 遮挡住的滚动视图添加属性)
- 绝对定位注意事项:跟vue页面一样,绝对定位的视图需要考虑 tabBar 的遮挡问题,例如想要一个 view 固定在页面最底部,需要设置 bottom 值为 tabBar 的高度即可;
示例
<template>
<!-- 页面根节点为滚动视图,并添加 adjustBottom="true" -->
<scroll-view class="content" scroll-y="true" adjustBottom="true">
<image v-for="index in 3" :key='index' src="../../static/test.png" style="width: 750rpx; height: 1136rpx;" mode="scaleToFill"></image>
<!-- 绝对定位的视图需要考虑 tabBar 遮挡的问题,bottom 应该加上 tabBar 的高度 -->
<view class="fixedView" :style="{ bottom : tabbarHeight + 'px'}"></view>
</scroll-view>
</template>
<script>
export default {
data() {
return {
tabbarHeight: 0
}
},
onReady() {
// 获取 tabBar 的高度
this.tabbarHeight = uni.getSystemInfoSync().windowBottom;
}
}
</script>
<style>
.content {
background-color: #FFFFFF;
line-height: 0;
}
.fixedView{
position: fixed;
width: 750rpx;
height: 30px;
background-color: #4CD964;
}
</style>
<a id="view"></a>
nvue view组件使用高斯模糊效果
HBuilderX 从 2.4.8+ 版本开始,IOS 端 nvue view组件支持高斯模糊效果(毛玻璃效果)。
效果
使用方法
在 view 组件中添加 blurEffect
属性启用高斯模糊效果,取值同 TabBar
- "dark" - 暗风格模糊,对应iOS原生UIBlurEffectStyleDark效果;
- "extralight" - 高亮风格模糊,对应iOS原生UIBlurEffectStyleExtraLight效果;
- "light" - 亮风格模糊,对应iOS原生UIBlurEffectStyleLight效果;
- "none" - 无模糊效果。
注意事项
- 启用高斯模糊效果后,不建议设置 background-color,如果非要设置的话需要使用
rgba
设置透明度,否则看不到模糊效果; - 启用高斯模糊效果后相当于 view 组件对应的视图变成了毛玻璃,透过 view 看下面的内容会有模糊效果, view 上添加的视图不受影响;
示例
<template>
<view class="container">
<image src="../../static/3.jpg" class="img" mode="aspectFill"></image>
<view class="blur" blurEffect="light">
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
}
}
</script>
<style>
.container{
flex: 1;
}
.img {
flex: 1;
}
.blur{
position: fixed;
top: 300rpx;
bottom: 300rpx;
left: 20px;
right: 20px;
/* background-color: rgba(152,245,255,0.3); */
}
</style>
navigationBar 使用高斯模糊效果
HBuilderX 从 2.4.4 版本开始,uni-app iOS 端 navigationBar 支持高斯模糊效果(毛玻璃效果)。
HBuilderX 从 3.4.10 版本开始,uni-app Android 端 navigationBar 支持高斯模糊效果(毛玻璃效果)。
使用方法
页面 style --> app-plus --> titleNView中添加 blurEffect
属性启用高斯模糊效果
- "dark" - 暗风格模糊,对应iOS原生UIBlurEffectStyleDark效果;
- "extralight" - 高亮风格模糊,对应iOS原生UIBlurEffectStyleExtraLight效果;
- "light" - 亮风格模糊,对应iOS原生UIBlurEffectStyleLight效果;
- "none" - 无模糊效果。
示例
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "vue",
"app-plus":{
"bounce":"vertical",
"titleNView": {
"blurEffect":"extralight",
"backgroundColor": "#00ffffff",
"type" : "float"
}
}
}
}
}
注意:backgroundColor需要设置带有透明度颜色才能看到高斯模糊效果。不设置backgroundColor也无法看到高斯模糊效果!
收起阅读 »
HBuilderX自定义主题
效果图:
(有个小小的问题,代码选中的背景颜色改不了好像=.=)
全部json代码:
{
"editor.caretWidth" : 1,
"editor.colorScheme" : "Default",
"editor.wordWrap" : true,
"explorer.autoReveal" : true,
"explorer.iconTheme" : "hx-file-icons-colorful",
"workbench.colorCustomizations" : {
"[Default]" : {
"sideBar.background" : "#FDF0ED", //加深项目管理器颜色
"editor.background" : "#FDF0ED", //加深编辑区域背景颜色
"toolBar.background" : "#FDF0ED",
"toolBar.hoverBackground" : "#fce5de",
"toolBar.border" : "#fad3c7",
"tab.activeBackground" : "#fad3c7", //选中时的背景颜色
"tab.activeForeground" : "#242227", //选中时的前景颜色
"tab.inactiveBackground" : "#FDF0ED", //未选中时的背景颜色
"tab.inactiveForeground" : "#938D8B", //未选中时的前景颜色
"tab.hoverBackground" : "#FCE7E2",
"tab.unfocusedHoverBackground" : "#FDF0ED", //未选中分栏里鼠标滑过未选中标签的背景颜色
"tab.unfocusedActiveForeground" : "#242227", //未选中分栏里选中标签的前景颜色
"tab.unfocusedInActiveForeground" : "#FDF0ED", //未选中分栏里选中标签的前景颜色
"editorSuggestWidget.selectedBackground" : "#fad3c7", //助手弹窗选中条目时背景颜色
"editorSuggestWidget.background" : "#fce5de", //助手弹窗背景颜色
"editorSuggestWidget.border" : "#fadad1", //助手弹窗边框颜色
"input.background" : "#fad3c7", //文本框背景颜色
"inputValidation.infoBackground" : "#FDF0ED", //下拉框背景颜色
"inputList.hoverBackground" : "#fce5de", //鼠标滑过item背景颜色
"inputList.border" : "#fce5de", //下拉框边框颜色
"list.foreground" : "#938D8B", //前景颜色
"list.highlightForeground" : "#E42E5B", //高亮时前景颜色
"list.activeSelectionBackground" : "#fad3c7", //选中条目背景颜色
"list.activeSelectionForeground" : "#E42E5B", //选中条目前景颜色
"list.hoverBackground" : "#fce5de", //鼠标滑过背景颜色
"outlineBackground" : "#FDF0ED", //文档结构背景颜色
"scrollbarSlider.background" : "#fad3c7", //滚动条背景颜色
"scrollbarSlider.hoverBackground" : "#E42E5B", //鼠标滑过滚动条背景颜色
"extensionButton.prominentBackground" : "#FDF0ED", //背景颜色
"extensionButton.prominentForeground" : "#E42E5B", //前景颜色
"extensionButton.border" : "#fad3c7", // 边框颜色
"extensionButton.prominentHoverBackground" : "#fad3c7", //鼠标滑过时的背景颜色
"extensionButton.checkColor" : "#E42E5B", //选中时的前景颜色
"settings.textInputBorder" : "#fadad1", //文本框边框颜色
"inputOption.activeBorder" : "#E42E5B", //文本框有焦点时边框颜色
"settings.dropdownBorder" : "#fadad1", // combobox下拉列表边框颜色
"settings.dropdownListBorder" : "#fadad1", //combobox item边框颜色
"imageview.background" : "#FDF0ED", //浅色方格颜色
"imageview.foreground" : "#fadad1", //深色方格颜色
"statusBar.background" : "#FDF0ED", //状态栏背景颜色
"statusBar.foreground" : "#938D8B", //状态栏前景颜色
"minimap.handle.background" : "#fadad1" //迷你地图滑块背景
}
}
}
发现好多小伙伴都不会用,我说一下吧,
先把主题换成默认的也就是绿柔主题(这样才会成功),
然后点工具/设置/源码视图,最右边栏(用户设置)的就是当前主题的代码,把它改成我发的上面的这个就好啦!
效果图:
(有个小小的问题,代码选中的背景颜色改不了好像=.=)
全部json代码:
{
"editor.caretWidth" : 1,
"editor.colorScheme" : "Default",
"editor.wordWrap" : true,
"explorer.autoReveal" : true,
"explorer.iconTheme" : "hx-file-icons-colorful",
"workbench.colorCustomizations" : {
"[Default]" : {
"sideBar.background" : "#FDF0ED", //加深项目管理器颜色
"editor.background" : "#FDF0ED", //加深编辑区域背景颜色
"toolBar.background" : "#FDF0ED",
"toolBar.hoverBackground" : "#fce5de",
"toolBar.border" : "#fad3c7",
"tab.activeBackground" : "#fad3c7", //选中时的背景颜色
"tab.activeForeground" : "#242227", //选中时的前景颜色
"tab.inactiveBackground" : "#FDF0ED", //未选中时的背景颜色
"tab.inactiveForeground" : "#938D8B", //未选中时的前景颜色
"tab.hoverBackground" : "#FCE7E2",
"tab.unfocusedHoverBackground" : "#FDF0ED", //未选中分栏里鼠标滑过未选中标签的背景颜色
"tab.unfocusedActiveForeground" : "#242227", //未选中分栏里选中标签的前景颜色
"tab.unfocusedInActiveForeground" : "#FDF0ED", //未选中分栏里选中标签的前景颜色
"editorSuggestWidget.selectedBackground" : "#fad3c7", //助手弹窗选中条目时背景颜色
"editorSuggestWidget.background" : "#fce5de", //助手弹窗背景颜色
"editorSuggestWidget.border" : "#fadad1", //助手弹窗边框颜色
"input.background" : "#fad3c7", //文本框背景颜色
"inputValidation.infoBackground" : "#FDF0ED", //下拉框背景颜色
"inputList.hoverBackground" : "#fce5de", //鼠标滑过item背景颜色
"inputList.border" : "#fce5de", //下拉框边框颜色
"list.foreground" : "#938D8B", //前景颜色
"list.highlightForeground" : "#E42E5B", //高亮时前景颜色
"list.activeSelectionBackground" : "#fad3c7", //选中条目背景颜色
"list.activeSelectionForeground" : "#E42E5B", //选中条目前景颜色
"list.hoverBackground" : "#fce5de", //鼠标滑过背景颜色
"outlineBackground" : "#FDF0ED", //文档结构背景颜色
"scrollbarSlider.background" : "#fad3c7", //滚动条背景颜色
"scrollbarSlider.hoverBackground" : "#E42E5B", //鼠标滑过滚动条背景颜色
"extensionButton.prominentBackground" : "#FDF0ED", //背景颜色
"extensionButton.prominentForeground" : "#E42E5B", //前景颜色
"extensionButton.border" : "#fad3c7", // 边框颜色
"extensionButton.prominentHoverBackground" : "#fad3c7", //鼠标滑过时的背景颜色
"extensionButton.checkColor" : "#E42E5B", //选中时的前景颜色
"settings.textInputBorder" : "#fadad1", //文本框边框颜色
"inputOption.activeBorder" : "#E42E5B", //文本框有焦点时边框颜色
"settings.dropdownBorder" : "#fadad1", // combobox下拉列表边框颜色
"settings.dropdownListBorder" : "#fadad1", //combobox item边框颜色
"imageview.background" : "#FDF0ED", //浅色方格颜色
"imageview.foreground" : "#fadad1", //深色方格颜色
"statusBar.background" : "#FDF0ED", //状态栏背景颜色
"statusBar.foreground" : "#938D8B", //状态栏前景颜色
"minimap.handle.background" : "#fadad1" //迷你地图滑块背景
}
}
}
发现好多小伙伴都不会用,我说一下吧,
先把主题换成默认的也就是绿柔主题(这样才会成功),
然后点工具/设置/源码视图,最右边栏(用户设置)的就是当前主题的代码,把它改成我发的上面的这个就好啦!

ios打包不成功的一种可能
打包失败返回原因如下:https://service.dcloud.net.cn/build/errorLog/31f75a40-11b7-11ea-bab1-e1536e25712c
嗯。。。。万万没想到是manifest下的图标配置错误,因为成功打包的安卓的图标是带圆角的,所以打包ios是就没有注意,用的同一个图标,结果看了https://ask.dcloud.net.cn/article/35979后才发现苹果的图标不能带圆角。。。。。分享给那些跟我一样粗心的孩子
所以,以后一定要看文档啊
打包失败返回原因如下:https://service.dcloud.net.cn/build/errorLog/31f75a40-11b7-11ea-bab1-e1536e25712c
嗯。。。。万万没想到是manifest下的图标配置错误,因为成功打包的安卓的图标是带圆角的,所以打包ios是就没有注意,用的同一个图标,结果看了https://ask.dcloud.net.cn/article/35979后才发现苹果的图标不能带圆角。。。。。分享给那些跟我一样粗心的孩子
所以,以后一定要看文档啊
收起阅读 »
uniapp 接口加密问题
接口采用3DES加密算法,加密模式CBC,填充方式PKCS7 Padding
1.首先安装 crypto-js npm install crypto-js --save-dev
2.新建 common/encrypt.js,内容:
var CryptoJS = require('crypto-js');
var key = '' //加密秘钥
var iv = '' //偏移量
module.exports = {
/**
* 加密
*/
encryptByDES:function (message) {
const keyHex = CryptoJS.enc.Utf8.parse(key);
const encrypted = CryptoJS.TripleDES.encrypt(message, keyHex, {
iv: CryptoJS.enc.Utf8.parse(iv),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
},
/**
* 解密
*/
decryptByDES:function (ciphertext) {
const keyHex = CryptoJS.enc.Utf8.parse(key);
// direct decrypt ciphertext
const decrypted = CryptoJS.TripleDES.decrypt({
ciphertext: CryptoJS.enc.Base64.parse(ciphertext)
}, keyHex, {
iv: CryptoJS.enc.Utf8.parse(iv),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
}
3.main.js
import Encrypt from './common/encrypt'
Vue.prototype.$encrypt = Encrypt
使用方式
this.$encrypt.encryptByDES(str) //加密
this.$encrypt.decryptByDES(str);//解密
接口采用3DES加密算法,加密模式CBC,填充方式PKCS7 Padding
1.首先安装 crypto-js npm install crypto-js --save-dev
2.新建 common/encrypt.js,内容:
var CryptoJS = require('crypto-js');
var key = '' //加密秘钥
var iv = '' //偏移量
module.exports = {
/**
* 加密
*/
encryptByDES:function (message) {
const keyHex = CryptoJS.enc.Utf8.parse(key);
const encrypted = CryptoJS.TripleDES.encrypt(message, keyHex, {
iv: CryptoJS.enc.Utf8.parse(iv),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
},
/**
* 解密
*/
decryptByDES:function (ciphertext) {
const keyHex = CryptoJS.enc.Utf8.parse(key);
// direct decrypt ciphertext
const decrypted = CryptoJS.TripleDES.decrypt({
ciphertext: CryptoJS.enc.Base64.parse(ciphertext)
}, keyHex, {
iv: CryptoJS.enc.Utf8.parse(iv),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
}
3.main.js
import Encrypt from './common/encrypt'
Vue.prototype.$encrypt = Encrypt
使用方式
this.$encrypt.encryptByDES(str) //加密
this.$encrypt.decryptByDES(str);//解密

scroll-view组件返回顶部不生效!(附第三方解决方案)
从https://uniapp.dcloud.io/component/scroll-view可以看到gotoTop()的实现,如下
goTop: function(e) {
this.scrollTop = this.old.scrollTop
this.$nextTick(function() { //这里应该是箭头函数
this.scrollTop = 0
});
uni.showToast({
icon:"none",
title:"纵向滚动 scrollTop 值已被修改为 0"
})
}
此前没太注意看这里。
今天遇到没法返回顶部的问题,经调试,滚动时,scrollTop一直都为0,而且再改为0,相当于没变化,也就是说界面其实没刷新。
后面改为100时,发现到100的位置,但当再次返回顶部,又不行了,猜测是因为数值没有变化,后来改为:
goTop: function(e) {
this.scrollTop = Math.random();
}
这样就好使了。
当然,还是建议用官方的方案,此文就当作是一种探讨吧~
从https://uniapp.dcloud.io/component/scroll-view可以看到gotoTop()的实现,如下
goTop: function(e) {
this.scrollTop = this.old.scrollTop
this.$nextTick(function() { //这里应该是箭头函数
this.scrollTop = 0
});
uni.showToast({
icon:"none",
title:"纵向滚动 scrollTop 值已被修改为 0"
})
}
此前没太注意看这里。
今天遇到没法返回顶部的问题,经调试,滚动时,scrollTop一直都为0,而且再改为0,相当于没变化,也就是说界面其实没刷新。
后面改为100时,发现到100的位置,但当再次返回顶部,又不行了,猜测是因为数值没有变化,后来改为:
goTop: function(e) {
this.scrollTop = Math.random();
}
这样就好使了。
当然,还是建议用官方的方案,此文就当作是一种探讨吧~
收起阅读 »
unipush 1.0常见问题
概述
本文旨在帮助使用 unipush 1.0 的用户解决集成或使用过程中常遇见的问题,让用户更顺畅地使用unipush,如按照本文介绍的内容排查问题之后仍有异常情况,可登录个推官网进行技术咨询。若您使用的是 uni-push 2.0 请查看: uni-push2.0 常见问题
uni-push1.0 常见问题
使用uniPush是否还需要重新注册个推开发者账号?
- 开发者无需重新注册个推账号,unipush与个推进行了直接打通,包括个推服务端api调用也只需要使用unipush应用内的参数。
云打包/离线打包集成问题
- 云打包教程请参考5+App开发入门指南【发行打包】部分。
- 由于离线打包涉及到Dcloud侧部分原生封装问题,请加DCloud原生开发者QQ交流群: 814228233 咨询解决。
厂商推送设置-->保存参数时提示:验证错误
- 原因是填写了错误的厂商参数,需要去对应的 厂商平台 核实参数是否一致,且注意填写时不能包含空格。
- 如果确认参数完全一致,可以更换浏览器后再进行填写保存,推荐使用 Google 浏览器。
如何获取CID和任务ID
- 在应用安装后第一次运行时应该调用5+ API的plus.push.getClientInfo方法获取客户端标识,如果获取的cid为空,说明客户端向推送服务器注册还未完成,可以使用setTimeout延时重试。
document.addEventListener('plusready', function(){ // 页面加载时触发 plus.push.getClientInfoAsync((info) => { let cid = info["clientid"]; }); }, false );
- 服务端推送的,请求成功后会返回result,result中【taskid】的值就是任务ID;平台上推送的,在【推送记录】中点击详情,页面上显示的【task ID】的值。
推送频次默认相关限制
- to single单推接口,推送没有限制。
- to list列表推接口,一天限制200万次,一次上限200个CID,相同消息体可复用taskid,只算一次次数。
- to app群推接口,一天限制100次,一分钟不能超过5次,10分钟内不能推重复消息体。
服务端推送返回报target user is invalid、appiderror
- 每个APP应用都有各自的一套Appid、Appkey、 AppSecret参数,个推的CID是与各个应用的Appid有对应绑定关系,以此来区分定位到各个手机上的app的。
- Unipush推送出现AppidError或者target user is invalid,一般都是您使用的CID是自定义基座包获取的,不属于您自己应用,属于Dcloud官方的测试app应用。您需要使用自有证书提交云打包后,下载安装再去获取正确的CID进行推送测试。Dcloud侧官方Appid : pPyZWvH3Fa6PXba10aJ009
Unipush平台上故障排查输入cid查询出现 cid不存在或应用错误
- 每个APP应用都有各自的一套Appid、Appkey、 AppSecret参数,个推的CID是与各个应用的Appid有对应绑定关系,以此来区分定位到各个手机上的app的。
- 检查cid输入是否错误,是否有空格。
- 使用自有证书提交云打包后,下载安装再去获取正确的CID进行推送测试。
别名、标签推送收不到问题
- 个推推送都是通过clientid进行定点推送,clientid是个推业务层中的对外用户标识,用于标识客户端身份,是个推SDK的唯一识别号,简称CID。
- 推送别名、标签前,需要将客户端CID与自定义的别名、标签进行绑定动作,绑定成功后,推送别名和标签才能将消息推送给别名、标签下对应绑定的CID。
- 客户端绑定别名、标签,请在CID回调后,也就是客户端getClientInfo后,去调用绑定别名、标签接口,否则会出现绑定失败的问题。
- 在【Uni Push】-【配置管理】-【别名管理】/【应用标签】可输入别名、CID/标签名,进行查询CID是否与别名和标签绑定成功;若应页面数据延迟问题查无结果,可提供别名、CID/标签名给到个推技术支持进行确认。
- 别名相关限制
- 别名名称:长度40字节,支持中、英文(区分大小写)、数字以及下划线
- 一个CID一天绑定别名和解绑别名次数各有50次机会
- 一个别名下最多绑定10个CID,若超出10个,则绑定后者,剔除第一个已绑定的CID,以此类推;一个CID只能绑定一个别名,若超出则以最后一次绑定的别名为准。
- 标签相关限制
- 标签名称:长度32字节,中文、英文字母(大小写)、数字、除英文逗号以外的其他特殊符号
- 一个CID一天默认绑定只有一次标签绑定次数。
- 一个CID默认可支持100个标签,标签的绑定是全量覆盖的,后面一次的覆盖前面一次的 。
安卓厂商离线推送是否要求上架应用商店?
- 目前华为、荣耀、魅族、oppo(测试环境)不要求上架应用商店;vivo 、小米、oppo(正式环境)必须上架应用商店后才可使用离线厂商推送。
找不到OPPO的mastersecret参数
- OPPO平台的mastersecret参数需要在应用通过推送审核后,使用主账号在oppo推送平台-配置管理-应用配置 页面查看。
离线通知没有声音、震动
- 检查手机通知权限中的响铃和震动状态是否打开,包括通知权限的各个通知渠道里的相关权限,例如华为的【营销通知】默认是没有声音、震动的;
- Ios离线的通知除检查手机系统通知设置样式外,还需检查服务端push_channel里aps中的sound参数是否设置值为default;若设置成com.gexin.ios.silence,则苹果离线不会有声音。
iOS在线推送消息时,app 闪退
一般是客户端抛异常了,需要在客户端的receive回调中判断msg.type是否为空。
华为离线推送消息自动归到【营销通知】
- 这是华为侧的消息控制:华为推送对推送消息分类进行管理,根据消息内容,华为推送将通知分类为服务与通讯、资讯营销两大类别。对应不同消息级别,会有不同的消息呈现样式。具体说明请参考 华为官方消息分类文档
- 个推侧服务端代码设置示例
"options": { "HW": { "/message/android/notification/importance": "NORMAL", } }
注意:该设置项不能直接决定消息分类,华为侧还是会通过消息体判断去划分,最终是以华为侧的划分为准。请尽量不要推送测试性消息,同样消息体也不要频繁重复推送
点击消息如何实现页面跳转
在线消息:
如果客户端发的是透传消息,消息到达客户端后会触发 receive 回调。客户端需要调用 createMessage 方法自己创建通知栏消息展示。点击通知栏消息会触发客户端的 click 回调,在回调中自行处理页面的跳转。
离线消息:
android:
- 服务端push_channel.android必须内必须设置安卓跳转页面的参数intent,参数为固定格式:intent://io.dcloud.unipush/?#Intent;scheme=unipush;launchFlags=0x4000000;component=请填您的包名/io.dcloud.PandoraEntry;S.UP-OL-SU=true;S.title=测试标题;S.content=测试内容;S.payload=test;end
- 由于Dcloud封装,使用固定的intent,消息点击默认只支持跳转到应用首页,不支持intent中直接给定Dcloud的插件页面路径。当用户点击通知后,会携带intent的值触发客户端click回调方法, 客户端可根据接收的参数再调用客户端跳转方法实现自定义页面跳转。
ios:
- 服务端push_channel.ios内必须设置ios的自定义参数payload,参数为任意值。
- 当用户点击通知后,会携带payload的值触发客户端receive回调方法, 客户端可根据接收的参数再调用客户端跳转方法实现自定义页面跳转。
客户端跳转app内指定页面的方法:
uni.navigateTo({
//页面路径示例值:/pages/pushinfo/pushinfo
url:'指定页面路径'
})
点击(click)事件不触发、(receive)事件不触发/监听不到。
- 离线点击不触发click事件,intent中要有dcloud要求的参数格式要求S.UP-OL-SU=true;S.title=测试标题;S.content=测试内容;S.payload=test;否则dcloud识别不到,无法进入对应回调
- 在线透传不触发receive事件,主要是安卓透传内容给了{title:"标题",content:"内容",payload:"自定义数据"}dcloud要求格式的透传内容,dcloud会默认处理展示通知栏通知,并且不会进入receive回调。
平台【预览】返回clientid离线
- 推送时的【预览】功能只支持测试个推在线通道,也就是CID在线的状态下,您输入clientid会进行预览推送测试;若是想测试离线,不需要输入clientid,直接点击【确定】进行推送即可。
【故障排查】-【推送测试】返回error,code:80502
- 【推送测试】功能目前是停止维护的状态,后期会去除该模块,因此目前建议您不要使用该功能,若需要推送测试,可直接在【创建推送】中直接建立推送进行测试。
Dcloud平台厂商参数保存后消失
- 这是正常现象,确保保存成功即可;但参数保存后需要通过提交云打包才能使新保存参数生效到应用中,因此厂商参数保存后,请一定要提交云打包。
自定义铃声是否支持
- 在线推送都支持自定义铃声,离线推送仅 华为、小米、ios 支持 。自定义推送铃声:https://ext.dcloud.net.cn/plugin?id=7482
角标怎么清理
- 调用 5+ API plus.runtime.setBadgeNumber
离线通知角标支持情况
- oppo/魅族,部分手机系统上能设置角标圆点,没有数字角标的功能。
- 小米系统自带离线通知数字角标展示功能,默认+1处理,打开清零。
- vivo高版本系统自带离线通知数字角标展示功能,默认+1处理,打开清零,低版本没有角标功能。
-
华为、荣耀、iOS 角标需服务端api进行字段设置,客户端需要手动设置角标数为 0 。 plus.runtime.setBadgeNumber
- 服务端rest-v2 api 的离线通知角标设置示例,注意:Unipush用户的class的值请固定使用'io.dcloud.PandoraEntry'
"push_channel": { "android": { "ups": { "notification": { "title": "厂商离线标题", "body": "厂商离线内容", "click_type": "url", "url": "https://www.getui.com/" }, "options": { "HW": { "/message/android/notification/badge/class": "io.dcloud.PandoraEntry", //add_num 为离线推送时,设置的华为角标,1表示在当前的角标数上+1 "/message/android/notification/badge/add_num": 1 }, "HO": { "/android/notification/badge/addNum": 1, //add_num 为离线推送时,设置的荣耀角标,1表示在当前的角标数上+1 "/android/notification/badge/badgeClass": "io.dcloud.PandoraEntry" } } } } "ios":{ "type":"notify", "payload":"自定义消息", "aps":{ "alert":{ "title":"通知标题", "body":"通知内容" }, "content-available":0 }, //离线走apns推送时,设置的iOS角标。 "auto_badge":"+1" //可以实现显示数字的自动增减,如“+1”、 “-1”、 “1” 等,计算结果将覆盖badge } }
- 服务端rest-v2 api 的离线通知角标设置示例,注意:Unipush用户的class的值请固定使用'io.dcloud.PandoraEntry'
安卓厂商离线机型版本支持情况
- 华为机型要求:需华为rom且华为rom版本大于等于emui4.1, 华为移动服务(可在应用列表或华为应用市
场中查看)版本大于等于2.5.2 - 小米机型要求:需小米rom且小米服务框架(包名:com.xiaomi.xmsf)版本号⼤于等于105
- 魅族机型要求:需魅族rom版本大于等于5.x
- oppo机型要求:需oppo colorOS rom且版本号大于等于3.1
- vivo机型要求:请参考vivo官网说明
CID什么情况下会变化
- 若安卓用户超过100天、 iOS用户超过一年,CID 一直没有登录请求(CID 没有与个推服务端建立长链接)。则 CID 会失效,之后再启动会重新生成一个CID;
- 如果应用没有获取sd卡权限,卸载重装/清除缓存,CID会变(CID信息会写入sd卡)。
- 个推Appid参数、应用的包名、苹果Bundleid的修改。
- 苹果手机进行了越狱或系统还原。
如何更换App图标
- 在HX编译器中可以设置。
Android常见问题
安卓消息推送流程说明
-
默认情况下:
- 当CID在线(即app在前台打开运行)时,消息通过个推通道下发到客户端,具体到服务端Rest-V2代码中,即push_message中的 notification 或 transmission 内容传递给客户端
- 当CID离线(即app在后台、锁屏、进程关闭)时,有开启对应厂商离线功能的,消息将通过个推侧请求对应厂商侧的服务端,具体到服务端Rest-V2代码中,即push_channel中的android中的 notification 内容传递给厂商,实际的消息是经由厂商服务器下发至客户端;对于没有开启对应厂商功能的,消息将存在个推的离线库中,等待CID在线,再通过个推通道下发到客户端
-
注意:安卓的消息推送,走了厂商通道的消息就不会再通过个推通道推送至客户端,反之亦是如此,即消息只会推送一次
-
服务端有 strategy 字段,可以控制消息走个推通道还是走厂商通道,设置示例参考个推侧说明。
- 1: 表示该消息在用户在线时推送个推通道,用户离线时推送厂商通道;
2: 表示该消息只通过厂商通道策略下发,不考虑用户是否在线;
3: 表示该消息只通过个推通道下发,不考虑用户是否在线;
4: 表示该消息优先从厂商通道下发,若消息内容在厂商通道代发失败后会从个推通道下发。 - 注意:2和4的前提是CID必须要正常绑定着安卓厂商token,Ios则是devicetoken,否则设置该策略会报错
- 1: 表示该消息在用户在线时推送个推通道,用户离线时推送厂商通道;
安卓在线收不到通知
- 手机通知权限是否正常打开,部分安卓8以上的手机通知权限中需要打开【Default】渠道的通知权限。
- 若服务端推送模板用的【Transmission】透传模板或平台上推送用的透传消息,且数据格式是自定义的json格式,需要客户端开发者在客户端【Receive】回调中接收该透传消息自己创建通知。
- 确认推送的CID与测试手机关系是否匹配;测试方式:在Dcloud后台【UniPush】-【配置管理】-【故障排查】-【 检测CID的状态及信息】中输入cid,然后多次关闭和打开app,检测每次app状态变化时,cid状态是否也会变化;若发现不对应,重新获取下客户端cid,以新的cid去进行推送测试。
安卓离线收不到通知
步骤一:确认CID是否绑定厂商token
在【Uni Push】-【配置管理】-【故障排查】-【 检测CID的状态及信息:】中输入CID查询,看是否会返回厂商token(device token)。
若返回了具体厂商token,请按以下中各厂商部分说明排查。若查询CID未返回token,请看下方步骤二
目前各厂商对离线消息有额度限制,例如华为单设备单应用每天只能收到 2 条营销类消息,超过后则当天收不到离线。详见 厂商通道限额&QPS说明 ,如果要提升额度,可以参考限额说明文档,向厂商申请系统、私信消息。
-
华为
- 标题长度限制40个字,内容长度限制1024个字。
- emui10的华为手机,检查手机通知权限设置,将【营销通知】的权限也打开,不要默认静默,静默的话是需要下拉通知栏才能看到。
- 手机通知栏消息是否有存满,清除已存的通知栏消息看下新的消息是否能展示。
- 华为【 资讯营销】,一个设备一天只能收到2条离线消息。
-
荣耀
- 荣耀【 资讯营销】,一个设备一天只能收到2条离线消息。
-
VIVO
- 标题长度限制20个字,内容长度限制50个字。
- 检查通知权限,vivo机型默认关闭
- 1个自然日内相同文案的运营消息给同个设备发,vivo会在客户端做去重处理,导致消息不展示
- vivo要求:通知文案中不能带 “包含测试、test字符”、“纯数字”、“纯表情”、“符号”或者“符号+数
字”、“表情+数字”、“表情+符号” - vivo需要上架至应用市场才能使用离线厂商推送。
- vivo【 公信消息】,一个设备一天只能收到2条离线消息。
-
小米
- 标题长度限制50个字,内容长度限制128个字。
- 检查手机通知权限设置,小米有不重要通知功能,部分消息可能会存在通知栏不重要通知里
- 服务端推送时,推送代码要加上离线时间设置,不能为空。
- 小米需要上架至应用市场才能使用离线厂商推送。
- 小米【 公信消息】,一个设备一天只能收到5条离线消息。
- 给小米设备推送消息时,必须要设置消息分类(/extra.channel_id),否则会被小米拦截。如何设置消息分类,详见:厂商通道限额&QPS说明
-
OPPO
- 标题长度限制32个字,内容长度限制200个字。
- 检查手机通知权限是否打开,oppo是默认关闭的,将通知权限下的【Default】通道权限也打开。
- 手机系统时间是否正常
- oppo【 公信消息】,一个设备一天只能收到2条离线消息。
-
魅族
- 标题长度限制32个字,内容长度限制100个字。
- 检查消息是否存入了魅族手机右上角【魅族消息盒子】中。
- 清除缓存:手机【系统设置】-【应用管理】-【所有应用】点击右上角【显示系统服务应用】找到【推送服务】和【您自己的 App】,如下图,分别进行“清除数据”,然后重启手机。
步骤二:查询CID未返回token,调试查询厂商code码
- 对应厂商平台上的推送服务状态是否是开启状态。
-
在Dcloud后台【Uni Push】-【厂商推送设置】中保存好厂商参数,并用自有证书提交云打包,且需要打正式包,再获取cid去查询是否有返回。
厂商错误码调试方法如下:
- 需要先安装调试环境,参考安装教程
- 手机连接电脑,手机需开启开发者调试模式,此时不用打开app
- Windows执行示例:如下图,回车执行后打开app
- Mac执行示例:如下图,回车执行后打开app
- 此时注意查看返回的厂商Code码,如上图中HW的错误码为907135702,点击下方链接搜索查询官方描述。
- 若未返回任何带有厂商标识的日志,说明厂商推送服务还未置于您app应用内,请重新检查厂商服务开通、配置、云打包相关步骤。
华为(包含荣耀)机型需要额外检查:
- 需要在华为开发者后台配置正确的 sha256 指纹证书
- 云打包用自有证书打正式签名包
- 华为开发者后台包名跟客户端包名需要保持一致
- 厂商推送设置-华为厂商,必须上传agconnect-services.json
- 在华为平台是否开通了华为推送服务
- 保存完参数,需要重新提交云端打包
步骤三:服务端推送代码问题
- push_message是个推在线时推送起作用的消息体;push_channel是个推离线时走厂商通道起作用的消息体 安卓厂商要用通知消息notification,ios厂商要用aps 。具体代码设置请参考文章末尾的厂商推送示例。
如何给华为、荣耀、vivo、oppo厂商发送测试消息
Android 厂商有离线推送的额度限制,基本都限制单设备单应用每天只能收到 2 条普通消息;如果要提升额度,可以自己向厂商申请消息分类。详见:厂商通道限额&QPS说明
开发测试阶段额度不足时,可以发送测试消息,目前仅华为、荣耀、vivo、oppo 支持下发测试消息。发送测试消息方式如下:
- 若调用服务端 api 推送,增加options参数:
"options": { "HW": { // 值为int 类型。1 表示华为测试消息,华为每个应用每日可发送该测试消息500条,此target_user_type 参数请勿发布至线上。 "/message/android/target_user_type":1 } , "HO": { //值为int 类型。1 表示测试推送,不填默认为0。荣耀每个应用每日可发送该测试消息1000条。此测试参数请勿发布至线上。 "/android/targetUserType": 1 }, "VV": { //值为int 类型。0 表示正式推送;1 表示测试推送,不填默认为0。线上请勿使用测试推送 "/pushMode":1 } }
vivo、oppo 发送测试消息,额外需要分别在 vivo 开放平台 、 oppo开放平台 录入测试用户(regid 对应个推cid 绑定的 device token,可以从个推后台的“故障排查”中查询 cid 信息获取)。
华为、荣耀不需要录入测试用户。华为、荣耀、vivo 需要在options内添加测试参数;oppo只需要添加测试设备,不需要options内加参数。
- 若从后台页面推送,填写红框附加参数:
”华为“ 、”/message/android/target_user_type”、”数字“ 、”1“(注意 1 是数字不是字符串)
”荣耀“ 、”/android/targetUserType”、”数字“ 、”1“(注意 1 是数字不是字符串)
”vivo“ 、”/pushMode”、”数字“ 、”1“(注意 1 是数字不是字符串)
iOS常见问题
iOS消息推送流程说明
- 当CID在线(即app在前台打开运行)时,消息通过个推通道下发到客户端,具体到服务端Rest-V2代码中,即push_message中的 transmission 透传内容传递给客户端。透传消息需要开发者在客户端receive透传回调中,接收透传消息并根据自身业务场景进行消息的展示方式处理,默认不处理的话是没有任何展示的,透传消息个推只负责传递。
- 当CID离线(即app在后台、锁屏)时,消息将通过个推侧请求对应厂商侧的服务端,具体到服务端Rest-V2代码中,即push_channel中的ios中的内容请求给苹果的服务端,由苹果进行推送。
- 注意:与安卓消息流程不同的是,Ios走了厂商离线通道,在消息有效期内,app打开在前台时,push_message中的 transmission 内容还将通过个推通道传递给客户端; 此时可在客户端透传回调中的参数PushMessage对象中获取aps属性值来判断是否是APNs下发的消息 ,参考推送开发指南
iOS在线收不到消息
- iOS推送,需要使用透传消息(服务端中push_message中使用的 transmission消息)
- 透传消息需要开发者在客户端receive透传回调中,接收透传消息并根据自身业务场景进行消息的展示方式处理,默认不处理的话是没有任何展示的,透传消息个推只负责传递。
- 确认推送的cid与测试手机关系是否匹配;测试方式:在Dcloud后台【UniPush】-【配置管理】-【故障排查】-【 检测CID的状态及信息】中输入cid,然后多次关闭和打开app,检测每次app状态变化时,cid状态是否也会变化;若发现不对应,重新获取下客户端cid,以新的cid去进行推送测试。
iOS离线收不到消息
步骤一:确认CID是否绑定苹果devicetoken
在【Uni Push】-【配置管理】-【故障排查】-【 检测CID的状态及信息:】中输入CID查询,看是否会返回苹果devicetoken。
若返回了具体苹果devicetoken,请按以下说明排查,若还未解决,提供CID和任务ID给个推技术支持
- 返回的devicetoken后面是否带着【developement】字样;若带着,则说明客户端环境是属于苹果的开发环境,苹果推送对开发环境的支持不稳定,建议使用正式环境去进行推送测试。
步骤二:查询CID未返回devicetoken
- 切换手机连接网络,卸载重装试下。
- 使用其他手机安装测试。
- 重新进行云打包。
步骤三:检测平台上传证书
- 在【配置管理】-【应用配置】-【测试一下】输入上述步骤查询出来的苹果devicetoken进行推送测试,看是否手机是否能收到,若报错则需重新导入苹果推送证书。
步骤四:服务端推送代码问题
- push_message是个推在线时推送起作用的消息体;push_channel是个推离线时走厂商通道起作用的消息体 安卓厂商要用通知消息notification,ios厂商要用aps 。具体代码设置请参考文章末尾的厂商推送示例。
证书测试一下返回无效、连接报错
- 证书环境问题:通用证书支持开发与正式环境推送;开发证书只支持开发环境推送。
- iOS证书的生成,请参考证书生成文档。
苹果证书上传后,选开发环境不对,选生产环境也不对;
- 导证书不要把钥匙串也导进来,解决按着证书生成文档重新导出次,单独选择证书;
Ios应用如何让角标badge自动加1
- 服务端推送时push_channeli中ios部分设置角标参数: "auto_badge":"+1"。
-
客户端需要做角标清零动作,原生示例代码如下,Dcloud可去论坛查询,接口方式与原生类似。
//重置角标 [GeTuiSdk resetBadge]; //如果需要角标清空需要调用系统方法设置 [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
概述
本文旨在帮助使用 unipush 1.0 的用户解决集成或使用过程中常遇见的问题,让用户更顺畅地使用unipush,如按照本文介绍的内容排查问题之后仍有异常情况,可登录个推官网进行技术咨询。若您使用的是 uni-push 2.0 请查看: uni-push2.0 常见问题
uni-push1.0 常见问题
使用uniPush是否还需要重新注册个推开发者账号?
- 开发者无需重新注册个推账号,unipush与个推进行了直接打通,包括个推服务端api调用也只需要使用unipush应用内的参数。
云打包/离线打包集成问题
- 云打包教程请参考5+App开发入门指南【发行打包】部分。
- 由于离线打包涉及到Dcloud侧部分原生封装问题,请加DCloud原生开发者QQ交流群: 814228233 咨询解决。
厂商推送设置-->保存参数时提示:验证错误
- 原因是填写了错误的厂商参数,需要去对应的 厂商平台 核实参数是否一致,且注意填写时不能包含空格。
- 如果确认参数完全一致,可以更换浏览器后再进行填写保存,推荐使用 Google 浏览器。
如何获取CID和任务ID
- 在应用安装后第一次运行时应该调用5+ API的plus.push.getClientInfo方法获取客户端标识,如果获取的cid为空,说明客户端向推送服务器注册还未完成,可以使用setTimeout延时重试。
document.addEventListener('plusready', function(){ // 页面加载时触发 plus.push.getClientInfoAsync((info) => { let cid = info["clientid"]; }); }, false );
- 服务端推送的,请求成功后会返回result,result中【taskid】的值就是任务ID;平台上推送的,在【推送记录】中点击详情,页面上显示的【task ID】的值。
推送频次默认相关限制
- to single单推接口,推送没有限制。
- to list列表推接口,一天限制200万次,一次上限200个CID,相同消息体可复用taskid,只算一次次数。
- to app群推接口,一天限制100次,一分钟不能超过5次,10分钟内不能推重复消息体。
服务端推送返回报target user is invalid、appiderror
- 每个APP应用都有各自的一套Appid、Appkey、 AppSecret参数,个推的CID是与各个应用的Appid有对应绑定关系,以此来区分定位到各个手机上的app的。
- Unipush推送出现AppidError或者target user is invalid,一般都是您使用的CID是自定义基座包获取的,不属于您自己应用,属于Dcloud官方的测试app应用。您需要使用自有证书提交云打包后,下载安装再去获取正确的CID进行推送测试。Dcloud侧官方Appid : pPyZWvH3Fa6PXba10aJ009
Unipush平台上故障排查输入cid查询出现 cid不存在或应用错误
- 每个APP应用都有各自的一套Appid、Appkey、 AppSecret参数,个推的CID是与各个应用的Appid有对应绑定关系,以此来区分定位到各个手机上的app的。
- 检查cid输入是否错误,是否有空格。
- 使用自有证书提交云打包后,下载安装再去获取正确的CID进行推送测试。
别名、标签推送收不到问题
- 个推推送都是通过clientid进行定点推送,clientid是个推业务层中的对外用户标识,用于标识客户端身份,是个推SDK的唯一识别号,简称CID。
- 推送别名、标签前,需要将客户端CID与自定义的别名、标签进行绑定动作,绑定成功后,推送别名和标签才能将消息推送给别名、标签下对应绑定的CID。
- 客户端绑定别名、标签,请在CID回调后,也就是客户端getClientInfo后,去调用绑定别名、标签接口,否则会出现绑定失败的问题。
- 在【Uni Push】-【配置管理】-【别名管理】/【应用标签】可输入别名、CID/标签名,进行查询CID是否与别名和标签绑定成功;若应页面数据延迟问题查无结果,可提供别名、CID/标签名给到个推技术支持进行确认。
- 别名相关限制
- 别名名称:长度40字节,支持中、英文(区分大小写)、数字以及下划线
- 一个CID一天绑定别名和解绑别名次数各有50次机会
- 一个别名下最多绑定10个CID,若超出10个,则绑定后者,剔除第一个已绑定的CID,以此类推;一个CID只能绑定一个别名,若超出则以最后一次绑定的别名为准。
- 标签相关限制
- 标签名称:长度32字节,中文、英文字母(大小写)、数字、除英文逗号以外的其他特殊符号
- 一个CID一天默认绑定只有一次标签绑定次数。
- 一个CID默认可支持100个标签,标签的绑定是全量覆盖的,后面一次的覆盖前面一次的 。
安卓厂商离线推送是否要求上架应用商店?
- 目前华为、荣耀、魅族、oppo(测试环境)不要求上架应用商店;vivo 、小米、oppo(正式环境)必须上架应用商店后才可使用离线厂商推送。
找不到OPPO的mastersecret参数
- OPPO平台的mastersecret参数需要在应用通过推送审核后,使用主账号在oppo推送平台-配置管理-应用配置 页面查看。
离线通知没有声音、震动
- 检查手机通知权限中的响铃和震动状态是否打开,包括通知权限的各个通知渠道里的相关权限,例如华为的【营销通知】默认是没有声音、震动的;
- Ios离线的通知除检查手机系统通知设置样式外,还需检查服务端push_channel里aps中的sound参数是否设置值为default;若设置成com.gexin.ios.silence,则苹果离线不会有声音。
iOS在线推送消息时,app 闪退
一般是客户端抛异常了,需要在客户端的receive回调中判断msg.type是否为空。
华为离线推送消息自动归到【营销通知】
- 这是华为侧的消息控制:华为推送对推送消息分类进行管理,根据消息内容,华为推送将通知分类为服务与通讯、资讯营销两大类别。对应不同消息级别,会有不同的消息呈现样式。具体说明请参考 华为官方消息分类文档
- 个推侧服务端代码设置示例
"options": { "HW": { "/message/android/notification/importance": "NORMAL", } }
注意:该设置项不能直接决定消息分类,华为侧还是会通过消息体判断去划分,最终是以华为侧的划分为准。请尽量不要推送测试性消息,同样消息体也不要频繁重复推送
点击消息如何实现页面跳转
在线消息:
如果客户端发的是透传消息,消息到达客户端后会触发 receive 回调。客户端需要调用 createMessage 方法自己创建通知栏消息展示。点击通知栏消息会触发客户端的 click 回调,在回调中自行处理页面的跳转。
离线消息:
android:
- 服务端push_channel.android必须内必须设置安卓跳转页面的参数intent,参数为固定格式:intent://io.dcloud.unipush/?#Intent;scheme=unipush;launchFlags=0x4000000;component=请填您的包名/io.dcloud.PandoraEntry;S.UP-OL-SU=true;S.title=测试标题;S.content=测试内容;S.payload=test;end
- 由于Dcloud封装,使用固定的intent,消息点击默认只支持跳转到应用首页,不支持intent中直接给定Dcloud的插件页面路径。当用户点击通知后,会携带intent的值触发客户端click回调方法, 客户端可根据接收的参数再调用客户端跳转方法实现自定义页面跳转。
ios:
- 服务端push_channel.ios内必须设置ios的自定义参数payload,参数为任意值。
- 当用户点击通知后,会携带payload的值触发客户端receive回调方法, 客户端可根据接收的参数再调用客户端跳转方法实现自定义页面跳转。
客户端跳转app内指定页面的方法:
uni.navigateTo({
//页面路径示例值:/pages/pushinfo/pushinfo
url:'指定页面路径'
})
点击(click)事件不触发、(receive)事件不触发/监听不到。
- 离线点击不触发click事件,intent中要有dcloud要求的参数格式要求S.UP-OL-SU=true;S.title=测试标题;S.content=测试内容;S.payload=test;否则dcloud识别不到,无法进入对应回调
- 在线透传不触发receive事件,主要是安卓透传内容给了{title:"标题",content:"内容",payload:"自定义数据"}dcloud要求格式的透传内容,dcloud会默认处理展示通知栏通知,并且不会进入receive回调。
平台【预览】返回clientid离线
- 推送时的【预览】功能只支持测试个推在线通道,也就是CID在线的状态下,您输入clientid会进行预览推送测试;若是想测试离线,不需要输入clientid,直接点击【确定】进行推送即可。
【故障排查】-【推送测试】返回error,code:80502
- 【推送测试】功能目前是停止维护的状态,后期会去除该模块,因此目前建议您不要使用该功能,若需要推送测试,可直接在【创建推送】中直接建立推送进行测试。
Dcloud平台厂商参数保存后消失
- 这是正常现象,确保保存成功即可;但参数保存后需要通过提交云打包才能使新保存参数生效到应用中,因此厂商参数保存后,请一定要提交云打包。
自定义铃声是否支持
- 在线推送都支持自定义铃声,离线推送仅 华为、小米、ios 支持 。自定义推送铃声:https://ext.dcloud.net.cn/plugin?id=7482
角标怎么清理
- 调用 5+ API plus.runtime.setBadgeNumber
离线通知角标支持情况
- oppo/魅族,部分手机系统上能设置角标圆点,没有数字角标的功能。
- 小米系统自带离线通知数字角标展示功能,默认+1处理,打开清零。
- vivo高版本系统自带离线通知数字角标展示功能,默认+1处理,打开清零,低版本没有角标功能。
-
华为、荣耀、iOS 角标需服务端api进行字段设置,客户端需要手动设置角标数为 0 。 plus.runtime.setBadgeNumber
- 服务端rest-v2 api 的离线通知角标设置示例,注意:Unipush用户的class的值请固定使用'io.dcloud.PandoraEntry'
"push_channel": { "android": { "ups": { "notification": { "title": "厂商离线标题", "body": "厂商离线内容", "click_type": "url", "url": "https://www.getui.com/" }, "options": { "HW": { "/message/android/notification/badge/class": "io.dcloud.PandoraEntry", //add_num 为离线推送时,设置的华为角标,1表示在当前的角标数上+1 "/message/android/notification/badge/add_num": 1 }, "HO": { "/android/notification/badge/addNum": 1, //add_num 为离线推送时,设置的荣耀角标,1表示在当前的角标数上+1 "/android/notification/badge/badgeClass": "io.dcloud.PandoraEntry" } } } } "ios":{ "type":"notify", "payload":"自定义消息", "aps":{ "alert":{ "title":"通知标题", "body":"通知内容" }, "content-available":0 }, //离线走apns推送时,设置的iOS角标。 "auto_badge":"+1" //可以实现显示数字的自动增减,如“+1”、 “-1”、 “1” 等,计算结果将覆盖badge } }
- 服务端rest-v2 api 的离线通知角标设置示例,注意:Unipush用户的class的值请固定使用'io.dcloud.PandoraEntry'
安卓厂商离线机型版本支持情况
- 华为机型要求:需华为rom且华为rom版本大于等于emui4.1, 华为移动服务(可在应用列表或华为应用市
场中查看)版本大于等于2.5.2 - 小米机型要求:需小米rom且小米服务框架(包名:com.xiaomi.xmsf)版本号⼤于等于105
- 魅族机型要求:需魅族rom版本大于等于5.x
- oppo机型要求:需oppo colorOS rom且版本号大于等于3.1
- vivo机型要求:请参考vivo官网说明
CID什么情况下会变化
- 若安卓用户超过100天、 iOS用户超过一年,CID 一直没有登录请求(CID 没有与个推服务端建立长链接)。则 CID 会失效,之后再启动会重新生成一个CID;
- 如果应用没有获取sd卡权限,卸载重装/清除缓存,CID会变(CID信息会写入sd卡)。
- 个推Appid参数、应用的包名、苹果Bundleid的修改。
- 苹果手机进行了越狱或系统还原。
如何更换App图标
- 在HX编译器中可以设置。
Android常见问题
安卓消息推送流程说明
-
默认情况下:
- 当CID在线(即app在前台打开运行)时,消息通过个推通道下发到客户端,具体到服务端Rest-V2代码中,即push_message中的 notification 或 transmission 内容传递给客户端
- 当CID离线(即app在后台、锁屏、进程关闭)时,有开启对应厂商离线功能的,消息将通过个推侧请求对应厂商侧的服务端,具体到服务端Rest-V2代码中,即push_channel中的android中的 notification 内容传递给厂商,实际的消息是经由厂商服务器下发至客户端;对于没有开启对应厂商功能的,消息将存在个推的离线库中,等待CID在线,再通过个推通道下发到客户端
-
注意:安卓的消息推送,走了厂商通道的消息就不会再通过个推通道推送至客户端,反之亦是如此,即消息只会推送一次
-
服务端有 strategy 字段,可以控制消息走个推通道还是走厂商通道,设置示例参考个推侧说明。
- 1: 表示该消息在用户在线时推送个推通道,用户离线时推送厂商通道;
2: 表示该消息只通过厂商通道策略下发,不考虑用户是否在线;
3: 表示该消息只通过个推通道下发,不考虑用户是否在线;
4: 表示该消息优先从厂商通道下发,若消息内容在厂商通道代发失败后会从个推通道下发。 - 注意:2和4的前提是CID必须要正常绑定着安卓厂商token,Ios则是devicetoken,否则设置该策略会报错
- 1: 表示该消息在用户在线时推送个推通道,用户离线时推送厂商通道;
安卓在线收不到通知
- 手机通知权限是否正常打开,部分安卓8以上的手机通知权限中需要打开【Default】渠道的通知权限。
- 若服务端推送模板用的【Transmission】透传模板或平台上推送用的透传消息,且数据格式是自定义的json格式,需要客户端开发者在客户端【Receive】回调中接收该透传消息自己创建通知。
- 确认推送的CID与测试手机关系是否匹配;测试方式:在Dcloud后台【UniPush】-【配置管理】-【故障排查】-【 检测CID的状态及信息】中输入cid,然后多次关闭和打开app,检测每次app状态变化时,cid状态是否也会变化;若发现不对应,重新获取下客户端cid,以新的cid去进行推送测试。
安卓离线收不到通知
步骤一:确认CID是否绑定厂商token
在【Uni Push】-【配置管理】-【故障排查】-【 检测CID的状态及信息:】中输入CID查询,看是否会返回厂商token(device token)。
若返回了具体厂商token,请按以下中各厂商部分说明排查。若查询CID未返回token,请看下方步骤二
目前各厂商对离线消息有额度限制,例如华为单设备单应用每天只能收到 2 条营销类消息,超过后则当天收不到离线。详见 厂商通道限额&QPS说明 ,如果要提升额度,可以参考限额说明文档,向厂商申请系统、私信消息。
-
华为
- 标题长度限制40个字,内容长度限制1024个字。
- emui10的华为手机,检查手机通知权限设置,将【营销通知】的权限也打开,不要默认静默,静默的话是需要下拉通知栏才能看到。
- 手机通知栏消息是否有存满,清除已存的通知栏消息看下新的消息是否能展示。
- 华为【 资讯营销】,一个设备一天只能收到2条离线消息。
-
荣耀
- 荣耀【 资讯营销】,一个设备一天只能收到2条离线消息。
-
VIVO
- 标题长度限制20个字,内容长度限制50个字。
- 检查通知权限,vivo机型默认关闭
- 1个自然日内相同文案的运营消息给同个设备发,vivo会在客户端做去重处理,导致消息不展示
- vivo要求:通知文案中不能带 “包含测试、test字符”、“纯数字”、“纯表情”、“符号”或者“符号+数
字”、“表情+数字”、“表情+符号” - vivo需要上架至应用市场才能使用离线厂商推送。
- vivo【 公信消息】,一个设备一天只能收到2条离线消息。
-
小米
- 标题长度限制50个字,内容长度限制128个字。
- 检查手机通知权限设置,小米有不重要通知功能,部分消息可能会存在通知栏不重要通知里
- 服务端推送时,推送代码要加上离线时间设置,不能为空。
- 小米需要上架至应用市场才能使用离线厂商推送。
- 小米【 公信消息】,一个设备一天只能收到5条离线消息。
- 给小米设备推送消息时,必须要设置消息分类(/extra.channel_id),否则会被小米拦截。如何设置消息分类,详见:厂商通道限额&QPS说明
-
OPPO
- 标题长度限制32个字,内容长度限制200个字。
- 检查手机通知权限是否打开,oppo是默认关闭的,将通知权限下的【Default】通道权限也打开。
- 手机系统时间是否正常
- oppo【 公信消息】,一个设备一天只能收到2条离线消息。
-
魅族
- 标题长度限制32个字,内容长度限制100个字。
- 检查消息是否存入了魅族手机右上角【魅族消息盒子】中。
- 清除缓存:手机【系统设置】-【应用管理】-【所有应用】点击右上角【显示系统服务应用】找到【推送服务】和【您自己的 App】,如下图,分别进行“清除数据”,然后重启手机。
步骤二:查询CID未返回token,调试查询厂商code码
- 对应厂商平台上的推送服务状态是否是开启状态。
-
在Dcloud后台【Uni Push】-【厂商推送设置】中保存好厂商参数,并用自有证书提交云打包,且需要打正式包,再获取cid去查询是否有返回。
厂商错误码调试方法如下:
- 需要先安装调试环境,参考安装教程
- 手机连接电脑,手机需开启开发者调试模式,此时不用打开app
- Windows执行示例:如下图,回车执行后打开app
- Mac执行示例:如下图,回车执行后打开app
- 此时注意查看返回的厂商Code码,如上图中HW的错误码为907135702,点击下方链接搜索查询官方描述。
- 若未返回任何带有厂商标识的日志,说明厂商推送服务还未置于您app应用内,请重新检查厂商服务开通、配置、云打包相关步骤。
华为(包含荣耀)机型需要额外检查:
- 需要在华为开发者后台配置正确的 sha256 指纹证书
- 云打包用自有证书打正式签名包
- 华为开发者后台包名跟客户端包名需要保持一致
- 厂商推送设置-华为厂商,必须上传agconnect-services.json
- 在华为平台是否开通了华为推送服务
- 保存完参数,需要重新提交云端打包
步骤三:服务端推送代码问题
- push_message是个推在线时推送起作用的消息体;push_channel是个推离线时走厂商通道起作用的消息体 安卓厂商要用通知消息notification,ios厂商要用aps 。具体代码设置请参考文章末尾的厂商推送示例。
如何给华为、荣耀、vivo、oppo厂商发送测试消息
Android 厂商有离线推送的额度限制,基本都限制单设备单应用每天只能收到 2 条普通消息;如果要提升额度,可以自己向厂商申请消息分类。详见:厂商通道限额&QPS说明
开发测试阶段额度不足时,可以发送测试消息,目前仅华为、荣耀、vivo、oppo 支持下发测试消息。发送测试消息方式如下:
- 若调用服务端 api 推送,增加options参数:
"options": { "HW": { // 值为int 类型。1 表示华为测试消息,华为每个应用每日可发送该测试消息500条,此target_user_type 参数请勿发布至线上。 "/message/android/target_user_type":1 } , "HO": { //值为int 类型。1 表示测试推送,不填默认为0。荣耀每个应用每日可发送该测试消息1000条。此测试参数请勿发布至线上。 "/android/targetUserType": 1 }, "VV": { //值为int 类型。0 表示正式推送;1 表示测试推送,不填默认为0。线上请勿使用测试推送 "/pushMode":1 } }
vivo、oppo 发送测试消息,额外需要分别在 vivo 开放平台 、 oppo开放平台 录入测试用户(regid 对应个推cid 绑定的 device token,可以从个推后台的“故障排查”中查询 cid 信息获取)。
华为、荣耀不需要录入测试用户。华为、荣耀、vivo 需要在options内添加测试参数;oppo只需要添加测试设备,不需要options内加参数。
- 若从后台页面推送,填写红框附加参数:
”华为“ 、”/message/android/target_user_type”、”数字“ 、”1“(注意 1 是数字不是字符串)
”荣耀“ 、”/android/targetUserType”、”数字“ 、”1“(注意 1 是数字不是字符串)
”vivo“ 、”/pushMode”、”数字“ 、”1“(注意 1 是数字不是字符串)
iOS常见问题
iOS消息推送流程说明
- 当CID在线(即app在前台打开运行)时,消息通过个推通道下发到客户端,具体到服务端Rest-V2代码中,即push_message中的 transmission 透传内容传递给客户端。透传消息需要开发者在客户端receive透传回调中,接收透传消息并根据自身业务场景进行消息的展示方式处理,默认不处理的话是没有任何展示的,透传消息个推只负责传递。
- 当CID离线(即app在后台、锁屏)时,消息将通过个推侧请求对应厂商侧的服务端,具体到服务端Rest-V2代码中,即push_channel中的ios中的内容请求给苹果的服务端,由苹果进行推送。
- 注意:与安卓消息流程不同的是,Ios走了厂商离线通道,在消息有效期内,app打开在前台时,push_message中的 transmission 内容还将通过个推通道传递给客户端; 此时可在客户端透传回调中的参数PushMessage对象中获取aps属性值来判断是否是APNs下发的消息 ,参考推送开发指南
iOS在线收不到消息
- iOS推送,需要使用透传消息(服务端中push_message中使用的 transmission消息)
- 透传消息需要开发者在客户端receive透传回调中,接收透传消息并根据自身业务场景进行消息的展示方式处理,默认不处理的话是没有任何展示的,透传消息个推只负责传递。
- 确认推送的cid与测试手机关系是否匹配;测试方式:在Dcloud后台【UniPush】-【配置管理】-【故障排查】-【 检测CID的状态及信息】中输入cid,然后多次关闭和打开app,检测每次app状态变化时,cid状态是否也会变化;若发现不对应,重新获取下客户端cid,以新的cid去进行推送测试。
iOS离线收不到消息
步骤一:确认CID是否绑定苹果devicetoken
在【Uni Push】-【配置管理】-【故障排查】-【 检测CID的状态及信息:】中输入CID查询,看是否会返回苹果devicetoken。
若返回了具体苹果devicetoken,请按以下说明排查,若还未解决,提供CID和任务ID给个推技术支持
- 返回的devicetoken后面是否带着【developement】字样;若带着,则说明客户端环境是属于苹果的开发环境,苹果推送对开发环境的支持不稳定,建议使用正式环境去进行推送测试。
步骤二:查询CID未返回devicetoken
- 切换手机连接网络,卸载重装试下。
- 使用其他手机安装测试。
- 重新进行云打包。
步骤三:检测平台上传证书
- 在【配置管理】-【应用配置】-【测试一下】输入上述步骤查询出来的苹果devicetoken进行推送测试,看是否手机是否能收到,若报错则需重新导入苹果推送证书。
步骤四:服务端推送代码问题
- push_message是个推在线时推送起作用的消息体;push_channel是个推离线时走厂商通道起作用的消息体 安卓厂商要用通知消息notification,ios厂商要用aps 。具体代码设置请参考文章末尾的厂商推送示例。
证书测试一下返回无效、连接报错
- 证书环境问题:通用证书支持开发与正式环境推送;开发证书只支持开发环境推送。
- iOS证书的生成,请参考证书生成文档。
苹果证书上传后,选开发环境不对,选生产环境也不对;
- 导证书不要把钥匙串也导进来,解决按着证书生成文档重新导出次,单独选择证书;
Ios应用如何让角标badge自动加1
- 服务端推送时push_channeli中ios部分设置角标参数: "auto_badge":"+1"。
-
客户端需要做角标清零动作,原生示例代码如下,Dcloud可去论坛查询,接口方式与原生类似。
//重置角标 [GeTuiSdk resetBadge]; //如果需要角标清空需要调用系统方法设置 [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];