Iphone APNs 推送通知调度的表情符号 Unicode 解码问题
Iphone emoji Unicode decode issue for push notification dispatch by APNs
我的网络服务向 APNs 发布推送通知并将 APNs 发送到目标 IOS 设备。
当 apns 在警报正文推送通知中包含 Unicode 表情符号并且 Iphone os 无法解码我的 Unicode 表情符号 '\uD83D\uDE0A' 应用程序已经终止。
推送通知显示相同的'\uD83D\uDE0A',顶部的横幅通知栏上没有显示表情符号。
Android 应用程序通过 GCM 发送推送通知正常工作但是 IOS 不支持。
Iphone-Ios只支持这种格式'\ue415'
这里是从 ActiveMQ 订阅聊天负载进入 web 服务的代码
public void onPublish(UTF8Buffer topic, Buffer msg, Runnable ack) {
try {
String body = msg.utf8().toString();
if (logger.isInfoEnabled()) {
logger.info("MQTT connection.listener.onPublish(), msg Received ["
+ body + "]");
}
if (body.contains("\"cmd\":\"chat\"")
&& body.contains("\"is_sender_msg\":true")) {
QueueMgr.addToChatQueue(body); //Changed true to false
}
else if(body.contains("\"cmd\":\"msg_seen\"")){
QueueMgr.addToChatReadSeenQueue(body);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
ack.run();
}
}
我在 java
上创建推送通知的代码
public static JSONObject constructePushJson(JSONObject jsonObject,String[] cloudkeyWithDevice) throws JSONException {
if(cloudkeyWithDevice[0] != null){
JSONObject pnAPIdata = new JSONObject();
if(cloudkeyWithDevice[1].equals("a") || cloudkeyWithDevice[1].equals("d")){
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_CMD, com.anyorg.constants.AppConstants.CMD_ANDROID_PUSH);
}
else{
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_CMD, com.anyorg.constants.AppConstants.CMD_IOS_PUSH);
}
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_APP_TOKEN, com.anyorg.constants.AppConstants.DEFAULT_APP_TOKEN);
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_DEVICE_TOKEN, cloudkeyWithDevice[0]);
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_USER_ID, jsonObject.getInt(com.anyorg.constants.AppConstants.FLD_TO_USER_ID));
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_DEVICE_ID, 0);
String alertMsg=StringEscapeUtils.unescapeJava(jsonObject.getString(com.anyorg.constants.AppConstants.FLD_BODY));
jsonObject.put(com.anyorg.constants.AppConstants.FLD_BODY,alertMsg);
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_ALERT_MSG, "AryaConnect: "+alertMsg);//(jsonObject.isNull("body")) ? jsonObject.getString("from_user_name")+": Sent a file" : jsonObject.getString("from_user_name")+": "+jsonObject.getString("body")
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_MSG, jsonObject);//jsonObject.getString(com.anyorg.constants.AppConstants.FLD_BODY)
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_CALLBACK_URL, callbackUrl);
pnAPIdata.put(com.anyorg.constants.AppConstants.MAC_ADDRESS_ID, jsonObject.getString("mobile_rec_id"));
return pnAPIdata;
}
else{
return null;
}
}
发布到 APNs 代码
public class ANSNotificationDispatcher implements NotificationDispatcher {
protected static final Logger logger = Logger
.getLogger(ANSNotificationDispatcher.class);
public static final String OS_NAME = AppConstants.OS_TYPE_IPHONE;
String keystore;
String password;
boolean production;
public ANSNotificationDispatcher() {
try {
keystore = AppConfig.getAPNKeystore();
password = AppConfig.getAPNKeystorePassword();
PushyAPNMgr.init(keystore, password, AppConfig.isAPNProdcution());
} catch (Throwable e) {
e.printStackTrace();
}
}
private void push(Payload payload, String token, String userId,
String deviceId) throws ConfigurationException,
DeviceUnregisteredException {
// QueueManager.addToIOsQueue(payLoad, token, userId, ivUserDeviceId);
long stime = System.currentTimeMillis();
try {
PushyAPNMgr.push(token, payload.toString());
if (logger.isInfoEnabled())
logger.info("push(): APN PN userId [" + userId
+ "], device id [" + deviceId + "] payoad [" + payload
+ "] Response time ["
+ (System.currentTimeMillis() - stime) + "]ms");
} catch (Exception e) {
e.printStackTrace();
throw new ConfigurationException();
}
}
public static Payload createComplexPayload(JSONObject jsonObject) {
PushNotificationPayload complexPayload = null;
try {
complexPayload = createPayload(jsonObject);
String msg = Common.getStringAsNull(jsonObject,
AppConstants.FLD_MSG);
if (!Common.isEmpty(msg)) {
complexPayload.addCustomDictionary(AppConstants.FLD_MSG, msg);
}
if (logger.isInfoEnabled()) {
logger.info("createComplexPayloadV2(): payload ["
+ complexPayload.getPayload().toString() + "]");
}
} catch (JSONException e) {
e.printStackTrace();
}
return complexPayload;
}
public void dispatch(JSONObject jsonObject, String jsonData)
throws NotificationException, DeviceUnregisteredException,
MultipleRegistartionIdException, ConfigurationException {
String deviceToken = Common.getStringAsNull(jsonObject,
AppConstants.FLD_DEVICE_TOKEN);
if (Common.isEmpty(deviceToken)) {
logger.error("dispatch(): device token is null, cmd [" + jsonData
+ "]");
return;
}
Payload payload = createComplexPayload(jsonObject);
String userId = Common.getStringAsNull(jsonObject,
AppConstants.FLD_USER_ID);
String deviceId = Common.getStringAsNull(jsonObject,
AppConstants.FLD_DEVICE_ID);
push(payload, deviceToken, userId, deviceId);
}
public static void handleInvalidTokeException(String token) {
}
public static void handleDeviceUnregisteredException(String token) {
}
}
Ios 由 Ios OS
管理的推送通知
我的 Apache Catalina 日志
我是一名 Web 服务云开发人员,前几天仅针对 Ios 应用程序面临此问题。所以请,如果有人有知识或以前做过。请告诉我一些想法。
我的推送通知中的表情符号 link。
https://mixpanel.com/help/questions/articles/how-do-i-send-custom-parameters-like-emoji-in-my-push-notifications
谢谢
你不需要搞乱 html 解码。正如您所说,笑脸的代码点是 \u263A。在 PHP 中,您可以在 UTF8 编码的字符串中将其表示为“\xE2\x98\xBA”
闪电(实际上'high voltage sign')是UTF-8中的\u26A1或“\xE2\x9A\xA1”。
这两个字符都作为常规 Unicode 符号出现在某些非表情符号字体中。你可以看到:
<?php
header('Content-type: text/html; charset=utf-8');
echo "\xE2\x9A\xA1";
echo "\xE2\x98\xBA";
或其他事情...
对于 google 员工。 json_encode() 添加双 \
$message = "\ue04a";
$body['aps'] = array(
'alert' => $message,
'sound' => 'default',
'type' => $type,
'param' => $param
);
$payload = json_encode($body);
$payload = str_replace("\", "\", $payload);
请用这两种方式检查...我认为这对您有帮助。
最后,通过此 Unicode 编码和解码过程,APNs 问题在 java Web 服务代码上的(Ios 应用程序)中得以解决。 (unescapeJava 和 escapeJava) 来自 lib commons-lang-2.6.jar 和 class org.apache.commons.lang.StringEscapeUtils
emojiBytes = alertMsg.getBytes("UTF-8");
text = new String(emojiBytes, "UTF-8");
private static PushNotificationPayload createPayload(JSONObject jsonObject)
throws JSONException {
String alertMsg = Common.getStringUnicodeAsNull1(jsonObject,
AppConstants.FLD_ALERT_MSG);
byte[] emojiBytes=null;
String text=null;
try {
emojiBytes = alertMsg.getBytes("UTF-8");
text = new String(emojiBytes, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//String emojiAsString = new String(emojiBytes, Charset.forName("UTF-8"));
//System.out.println("@@@@@alertMsg: "+text);
Integer badgeCnt;
if (jsonObject.has(AppConstants.FLD_BADGE_CNT)){
badgeCnt = Common.getIntegerAsNull(jsonObject,
AppConstants.FLD_BADGE_CNT);
}else{
badgeCnt = AppConstants.VAL_ZERO;
}
PushNotificationPayload payload = createPayload(badgeCnt, text);
return payload;
}
String alertMsg = Common.getStringUnicodeAsNull1(jsonObject,
AppConstants.FLD_ALERT_MSG);
public static String getStringUnicodeAsNull1(JSONObject jsonObject,
String key) {
try {
if(jsonObject.isNull(key))
return null;
else
return StringEscapeUtils.unescapeJava(jsonObject.getString(key));
} catch (JSONException je) {
return null;
}
}
尊敬的先生和女士,如果 IOS 推送通知上的 java APNs 表情符号 Unicode 有任何其他解决方案。
那请给我一些提示。
谢谢
我的网络服务向 APNs 发布推送通知并将 APNs 发送到目标 IOS 设备。 当 apns 在警报正文推送通知中包含 Unicode 表情符号并且 Iphone os 无法解码我的 Unicode 表情符号 '\uD83D\uDE0A' 应用程序已经终止。
推送通知显示相同的'\uD83D\uDE0A',顶部的横幅通知栏上没有显示表情符号。
Android 应用程序通过 GCM 发送推送通知正常工作但是 IOS 不支持。 Iphone-Ios只支持这种格式'\ue415'
这里是从 ActiveMQ 订阅聊天负载进入 web 服务的代码
public void onPublish(UTF8Buffer topic, Buffer msg, Runnable ack) {
try {
String body = msg.utf8().toString();
if (logger.isInfoEnabled()) {
logger.info("MQTT connection.listener.onPublish(), msg Received ["
+ body + "]");
}
if (body.contains("\"cmd\":\"chat\"")
&& body.contains("\"is_sender_msg\":true")) {
QueueMgr.addToChatQueue(body); //Changed true to false
}
else if(body.contains("\"cmd\":\"msg_seen\"")){
QueueMgr.addToChatReadSeenQueue(body);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
ack.run();
}
}
我在 java
上创建推送通知的代码public static JSONObject constructePushJson(JSONObject jsonObject,String[] cloudkeyWithDevice) throws JSONException {
if(cloudkeyWithDevice[0] != null){
JSONObject pnAPIdata = new JSONObject();
if(cloudkeyWithDevice[1].equals("a") || cloudkeyWithDevice[1].equals("d")){
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_CMD, com.anyorg.constants.AppConstants.CMD_ANDROID_PUSH);
}
else{
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_CMD, com.anyorg.constants.AppConstants.CMD_IOS_PUSH);
}
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_APP_TOKEN, com.anyorg.constants.AppConstants.DEFAULT_APP_TOKEN);
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_DEVICE_TOKEN, cloudkeyWithDevice[0]);
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_USER_ID, jsonObject.getInt(com.anyorg.constants.AppConstants.FLD_TO_USER_ID));
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_DEVICE_ID, 0);
String alertMsg=StringEscapeUtils.unescapeJava(jsonObject.getString(com.anyorg.constants.AppConstants.FLD_BODY));
jsonObject.put(com.anyorg.constants.AppConstants.FLD_BODY,alertMsg);
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_ALERT_MSG, "AryaConnect: "+alertMsg);//(jsonObject.isNull("body")) ? jsonObject.getString("from_user_name")+": Sent a file" : jsonObject.getString("from_user_name")+": "+jsonObject.getString("body")
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_MSG, jsonObject);//jsonObject.getString(com.anyorg.constants.AppConstants.FLD_BODY)
pnAPIdata.put(com.anyorg.constants.AppConstants.FLD_CALLBACK_URL, callbackUrl);
pnAPIdata.put(com.anyorg.constants.AppConstants.MAC_ADDRESS_ID, jsonObject.getString("mobile_rec_id"));
return pnAPIdata;
}
else{
return null;
}
}
发布到 APNs 代码
public class ANSNotificationDispatcher implements NotificationDispatcher {
protected static final Logger logger = Logger
.getLogger(ANSNotificationDispatcher.class);
public static final String OS_NAME = AppConstants.OS_TYPE_IPHONE;
String keystore;
String password;
boolean production;
public ANSNotificationDispatcher() {
try {
keystore = AppConfig.getAPNKeystore();
password = AppConfig.getAPNKeystorePassword();
PushyAPNMgr.init(keystore, password, AppConfig.isAPNProdcution());
} catch (Throwable e) {
e.printStackTrace();
}
}
private void push(Payload payload, String token, String userId,
String deviceId) throws ConfigurationException,
DeviceUnregisteredException {
// QueueManager.addToIOsQueue(payLoad, token, userId, ivUserDeviceId);
long stime = System.currentTimeMillis();
try {
PushyAPNMgr.push(token, payload.toString());
if (logger.isInfoEnabled())
logger.info("push(): APN PN userId [" + userId
+ "], device id [" + deviceId + "] payoad [" + payload
+ "] Response time ["
+ (System.currentTimeMillis() - stime) + "]ms");
} catch (Exception e) {
e.printStackTrace();
throw new ConfigurationException();
}
}
public static Payload createComplexPayload(JSONObject jsonObject) {
PushNotificationPayload complexPayload = null;
try {
complexPayload = createPayload(jsonObject);
String msg = Common.getStringAsNull(jsonObject,
AppConstants.FLD_MSG);
if (!Common.isEmpty(msg)) {
complexPayload.addCustomDictionary(AppConstants.FLD_MSG, msg);
}
if (logger.isInfoEnabled()) {
logger.info("createComplexPayloadV2(): payload ["
+ complexPayload.getPayload().toString() + "]");
}
} catch (JSONException e) {
e.printStackTrace();
}
return complexPayload;
}
public void dispatch(JSONObject jsonObject, String jsonData)
throws NotificationException, DeviceUnregisteredException,
MultipleRegistartionIdException, ConfigurationException {
String deviceToken = Common.getStringAsNull(jsonObject,
AppConstants.FLD_DEVICE_TOKEN);
if (Common.isEmpty(deviceToken)) {
logger.error("dispatch(): device token is null, cmd [" + jsonData
+ "]");
return;
}
Payload payload = createComplexPayload(jsonObject);
String userId = Common.getStringAsNull(jsonObject,
AppConstants.FLD_USER_ID);
String deviceId = Common.getStringAsNull(jsonObject,
AppConstants.FLD_DEVICE_ID);
push(payload, deviceToken, userId, deviceId);
}
public static void handleInvalidTokeException(String token) {
}
public static void handleDeviceUnregisteredException(String token) {
}
}
Ios 由 Ios OS
管理的推送通知我的 Apache Catalina 日志
你不需要搞乱 html 解码。正如您所说,笑脸的代码点是 \u263A。在 PHP 中,您可以在 UTF8 编码的字符串中将其表示为“\xE2\x98\xBA”
闪电(实际上'high voltage sign')是UTF-8中的\u26A1或“\xE2\x9A\xA1”。
这两个字符都作为常规 Unicode 符号出现在某些非表情符号字体中。你可以看到:
<?php
header('Content-type: text/html; charset=utf-8');
echo "\xE2\x9A\xA1";
echo "\xE2\x98\xBA";
或其他事情...
对于 google 员工。 json_encode() 添加双 \
$message = "\ue04a";
$body['aps'] = array(
'alert' => $message,
'sound' => 'default',
'type' => $type,
'param' => $param
);
$payload = json_encode($body);
$payload = str_replace("\", "\", $payload);
请用这两种方式检查...我认为这对您有帮助。
最后,通过此 Unicode 编码和解码过程,APNs 问题在 java Web 服务代码上的(Ios 应用程序)中得以解决。 (unescapeJava 和 escapeJava) 来自 lib commons-lang-2.6.jar 和 class org.apache.commons.lang.StringEscapeUtils
emojiBytes = alertMsg.getBytes("UTF-8");
text = new String(emojiBytes, "UTF-8");
private static PushNotificationPayload createPayload(JSONObject jsonObject)
throws JSONException {
String alertMsg = Common.getStringUnicodeAsNull1(jsonObject,
AppConstants.FLD_ALERT_MSG);
byte[] emojiBytes=null;
String text=null;
try {
emojiBytes = alertMsg.getBytes("UTF-8");
text = new String(emojiBytes, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//String emojiAsString = new String(emojiBytes, Charset.forName("UTF-8"));
//System.out.println("@@@@@alertMsg: "+text);
Integer badgeCnt;
if (jsonObject.has(AppConstants.FLD_BADGE_CNT)){
badgeCnt = Common.getIntegerAsNull(jsonObject,
AppConstants.FLD_BADGE_CNT);
}else{
badgeCnt = AppConstants.VAL_ZERO;
}
PushNotificationPayload payload = createPayload(badgeCnt, text);
return payload;
}
String alertMsg = Common.getStringUnicodeAsNull1(jsonObject, AppConstants.FLD_ALERT_MSG);
public static String getStringUnicodeAsNull1(JSONObject jsonObject,
String key) {
try {
if(jsonObject.isNull(key))
return null;
else
return StringEscapeUtils.unescapeJava(jsonObject.getString(key));
} catch (JSONException je) {
return null;
}
}
那请给我一些提示。
谢谢