我的android应用程序不会在后台接收推送通知,它应该符合documentation的要求。
Android设备上的Android应用程序不需要运行
接收信息。系统将唤醒Android应用程序
当消息到达时通过意图广播,只要
应用程序是用适当的广播接收器和
权限。
尝试不同的通知时发现,它确实在关闭时接收推送通知,如果且仅当通知包含属性“message”,如果不包含,它将丢弃它。(推送通知只是json对象)。
我的通知包含所有类型的属性,包括“alert”、“id”和“title”,但只有“message”能让android唤醒应用程序。
不起作用的通知示例:
{ event: 'message',
from: '947957531940',
collapse_key: 'do_not_collapse',
foreground: true,
payload:
{ alert: 'Mensaje de Prueba',
title: 'Titulo Mensaje de Prueba' } }
有效的通知示例:
{ event: 'message',
from: '947957531940',
message: 'Contenido del mensaje de prueba.',
collapse_key: 'do_not_collapse',
foreground: true,
payload:
{ alert: 'Mensaje de Prueba',
title: 'Titulo Mensaje de Prueba',
message: 'Contenido del mensaje de prueba.' } }
这是android的设计标准还是我在我的应用程序中做错了什么?
我的应用程序是用Ionic和Cordova开发的。
警察:请原谅我的英语。
编辑:
这是app.js中.run模块中的android推送代码,正如ng-cordova指令所指定的:
if (ionic.Platform.isAndroid()){
var androidConfig = {
"senderID": "94*************",
"ecb": "window.casosPush"
};
try{
var pushNotification = window.plugins.pushNotification;
} catch (ex){
}
// Llamada en caso de exito
var successfn = function(result){
//alert("Success: " + result);
};
// Llamada en caso de error
var errorfn = function(result){
window.alert("Error: " + result);
};
// Llamada de casos de notificacion push
window.casosPush = function(notification){
switch (notification.event){
case 'registered':
if (notification.regid.length > 0){
$rootScope.data.token = notification.regid;
//alert('registration ID = ' + notification.regid);
}
break;
case 'message':
$rootScope.mensajes.unshift(notification.payload);
$localstorage.setArray('mensajes', $rootScope.mensajes);
alert(JSON.stringify(notification));
break;
case 'error':
alert('GCM error = ' + notification.msg);
break;
default:
alert('An unknown GCM event has occurred');
break;
}
};
try{
// Llamada de registro con la plataforma GCM
pushNotification.register(successfn,errorfn,androidConfig);
} catch(notification){
}
}
最佳答案
在stackoverflow中搜索了所有涉及cordova/phonegap推送插件的问题之后,我找到了问题的源代码。是用插件的源代码写的,不应该。
问题是插件源代码要求推送通知具有“消息”字段,以便在后台触发通知。它在gcminentservice.java文件中得到了特别说明。
if (extras.getString("message") != null && extras.getString("message").length() != 0) {
createNotification(context, extras);
}
最有用的帖子是插件库中的thisanswer和thisissue。因此,因为我没有对推送服务器操作的权限,所以无法在推送通知中指定“消息”字段,所以除了重写源代码之外,我别无选择。
所以我重写了如下代码:
@Override
protected void onMessage(Context context, Intent intent) {
Log.d(TAG, "onMessage - context: " + context);
// Extract the payload from the message
Bundle extras = intent.getExtras();
if (extras != null)
{
// if we are in the foreground, just surface the payload, else post it to the statusbar
if (PushPlugin.isInForeground()) {
extras.putBoolean("foreground", true);
PushPlugin.sendExtras(extras);
}
else {
extras.putBoolean("foreground", false);
// Send a notification if there is a message
//if (extras.getString("message") != null && extras.getString("message").length() != 0) {
if (extras.getString("alert") != null && extras.getString("alert").length() != 0) {
createNotification(context, extras);
}
}
}
}
这样,如果插件接收到带有字段“alert”而不是“message”的推送通知,它就会触发本地通知。
然后,我更改了本地通知本身的代码:
public void createNotification(Context context, Bundle extras)
{
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
String appName = getAppName(this);
Intent notificationIntent = new Intent(this, PushHandlerActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationIntent.putExtra("pushBundle", extras);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
int defaults = Notification.DEFAULT_ALL;
if (extras.getString("defaults") != null) {
try {
defaults = Integer.parseInt(extras.getString("defaults"));
} catch (NumberFormatException e) {}
}
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setDefaults(defaults)
.setSmallIcon(context.getApplicationInfo().icon)
.setWhen(System.currentTimeMillis())
//.setContentTitle(extras.getString("title"))
.setContentTitle(extras.getString("alert"))
//.setTicker(extras.getString("title"))
.setTicker(extras.getString("alert"))
.setContentIntent(contentIntent)
.setAutoCancel(true);
/*
String message = extras.getString("message");
if (message != null) {
mBuilder.setContentText(message);
} else {
mBuilder.setContentText("<missing message content>");
}
*/
// Agregado mensaje predefinido
mBuilder.setContentText("Haz clic para más información");
String msgcnt = extras.getString("msgcnt");
if (msgcnt != null) {
mBuilder.setNumber(Integer.parseInt(msgcnt));
}
int notId = 0;
try {
notId = Integer.parseInt(extras.getString("notId"));
}
catch(NumberFormatException e) {
Log.e(TAG, "Number format exception - Error parsing Notification ID: " + e.getMessage());
}
catch(Exception e) {
Log.e(TAG, "Number format exception - Error parsing Notification ID" + e.getMessage());
}
mNotificationManager.notify((String) appName, notId, mBuilder.build());
}
现在,通知栏中的通知将首先显示字段“alert”而不是“title”,然后显示预定义的消息,而不是推送通知中不存在的字段“message”。
然后我重新编译代码:
ionic platform rm android
ionic platform add android
ionic run android
所以孩子们,当你为每个人编写一个插件,但你不考虑一般情况,你没有很好的文档时,就会发生这种情况。这个插件只对推送通知中有“消息”和“标题”字段的人有用。
因为这个,我失去了两天的实习时间,我花时间写了这篇文章,这样其他人就不用写了。
关于android - Ionic/Cordova应用程序不会在后台接收推送通知,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31212507/