gpt4 book ai didi

android - 应用程序在后台时,Cordova 本地通知不起作用

转载 作者:行者123 更新时间:2023-11-29 00:16:07 25 4
gpt4 key购买 nike

我正在使用 Cordova 开发一个 Android 应用程序,它使用 PushPlugin 从我的服务器接收推送通知。

特别是,我正在使用 PushPlugin Example 进行一些测试.

我也在使用 Cordova Local Notification plugin因为我希望应用在收到推送通知后立即显示本地通知。

以下代码有效并且本地通知出现,但仅当应用程序位于前台时。

我希望即使应用程序在后台也能显示本地通知。是否可以?我怎样才能让它发挥作用?

提前致谢

<!DOCTYPE HTML>
<html>
<head>
<title>com.PhoneGap.c2dm</title>
</head>
<body>

<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script type="text/javascript" charset="utf-8" src="jquery_1.5.2.min.js"></script>
<script type="text/javascript" src="PushNotification.js"></script>

<script type="text/javascript">
var pushNotification;

function onDeviceReady() {
$("#app-status-ul").append('<li>deviceready event received</li>');

document.addEventListener("backbutton", function(e){
$("#app-status-ul").append('<li>backbutton event received</li>');

if( $("#home").length > 0){
// call this to get a new token each time. don't call it to reuse existing token.
//pushNotification.unregister(successHandler, errorHandler);
e.preventDefault();
navigator.app.exitApp();
}
else{
navigator.app.backHistory();
}
}, false);
try{
pushNotification = window.plugins.pushNotification;
$("#app-status-ul").append('<li>registering ' + device.platform + '</li>');
if (device.platform == 'android' || device.platform == 'Android' || device.platform == 'amazon-fireos' ){
pushNotification.register(successHandler, errorHandler, {"senderID":"527085141383","ecb":"onNotification"});
} else {
pushNotification.register(tokenHandler, errorHandler, {"badge":"true","sound":"true","alert":"true","ecb":"onNotificationAPN"}); // obbligatorio!
}
}
catch(err) {
txt="There was an error on this page.\n\n";
txt+="Error description: " + err.message + "\n\n";
alert(txt);
}
} // fine onDeviceReady


function onNotificationAPN(e) {
if (e.alert) {
$("#app-status-ul").append('<li>push-notification: ' + e.alert + '</li>');
// showing an alert also requires the org.apache.cordova.dialogs plugin
navigator.notification.alert(e.alert);
}

if (e.sound) {
// playing a sound also requires the org.apache.cordova.media plugin
var snd = new Media(e.sound);
snd.play();
}

if (e.badge) {
pushNotification.setApplicationIconBadgeNumber(successHandler, e.badge);
}
}

function onNotification(e) {
$("#app-status-ul").append('<li>EVENT -> RECEIVED:' + e.event + '</li>');

switch( e.event ){
case 'registered':
if ( e.regid.length > 0 )
{
$("#app-status-ul").append('<li>REGISTERED -> REGID:' + e.regid + "</li>");
// Your GCM push server needs to know the regID before it can push to this device
// here is where you might want to send it the regID for later use.
console.log("regID = " + e.regid);
}
break;

case 'message':
// if this flag is set, this notification happened while we were in the foreground.
// you might want to play a sound to get the user's attention, throw up a dialog, etc.

var notificaOk = function(){
console.log("OK");
}
var notificaKo = function(){
console.log("KO");
}

window.plugin.notification.local.add({id: 1, title: "Product available", message: "Nexus 6 in stock", smallIcon: 'ic_dialog_email', icon: 'ic_launcher'}, notificaOk, notificaKo);

if (e.foreground){
$("#app-status-ul").append('<li>--INLINE NOTIFICATION--' + '</li>');

// on Android soundname is outside the payload.
// On Amazon FireOS all custom attributes are contained within payload
var soundfile = e.soundname || e.payload.sound;
// if the notification contains a soundname, play it.
// playing a sound also requires the org.apache.cordova.media plugin
var my_media = new Media("/android_asset/www/"+ soundfile);

my_media.play();

}
else{ // otherwise we were launched because the user touched a notification in the notification tray.

if (e.coldstart)
$("#app-status-ul").append('<li>--COLDSTART NOTIFICATION--' + '</li>');
else
$("#app-status-ul").append('<li>--BACKGROUND NOTIFICATION--' + '</li>');
}

$("#app-status-ul").append('<li>MESSAGE -> MSG: ' + e.payload.message + '</li>');
//android only
$("#app-status-ul").append('<li>MESSAGE -> MSGCNT: ' + e.payload.msgcnt + '</li>');
//amazon-fireos only
$("#app-status-ul").append('<li>MESSAGE -> TIMESTAMP: ' + e.payload.timeStamp + '</li>');

break;

case 'error':
$("#app-status-ul").append('<li>ERROR -> MSG:' + e.msg + '</li>');
break;

default:
$("#app-status-ul").append('<li>EVENT -> Unknown, an event was received and we do not know what it is</li>');
break;
}
}

function tokenHandler (result) {
$("#app-status-ul").append('<li>token: '+ result +'</li>');
// Your iOS push server needs to know the token before it can push to this device
// here is where you might want to send it the token for later use.
}

function successHandler (result) {
$("#app-status-ul").append('<li>success:'+ result +'</li>');
}

function errorHandler (error) {
$("#app-status-ul").append('<li>error:'+ error +'</li>');
}

document.addEventListener('deviceready', onDeviceReady, true);

</script>
<div id="home">
<div id="app-status-div">
<ul id="app-status-ul">
<li>Cordova PushNotification Plugin Demo</li>
</ul>
</div>
</div>
</body>
</html>

然后我使用以下 nodeJS 脚本向我的设备发送推送通知:

var GCM = require('gcm').GCM;

var apiKey = "***";

var gcm = new GCM(apiKey);

var devRegIdTarget = "APA9....";

var message = {
message: "Text msg",
registration_id : devRegIdTarget,
title : 'Title',
msgcnt : '1',
collapseKey : "msg1",
soundname : 'beep.wav'
};

message.timeToLive = 3000;
message.delayWhileIdle = true;

gcm.send(message, function(err, messageId){
if (err) {
console.log("Something has gone wrong!");
} else {
console.log("Sent with message ID: ", messageId);
}
});

最佳答案

我在使用 PushPlugin 和 LocalNotification 时有过类似的经历。

就我而言,通知在后台运行,但 android 的小图标是空白的。

我花了一整夜检查 LocalNotification 插件的源码,结果发现是 PushPlugin 本身的问题。 (我会说,确切的问题是两个插件之间的断开连接)在 PushPlugin 的源代码中,它检查应用程序是在前台还是后台。

如果应用程序在后台,则通知事件不会触发到 cordova 应用程序,但 PushPlugin 会自行创建它自己的本地通知。

    @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) {
createNotification(context, extras);
}
}
}
}

所以,如果你想在后台运行应用程序时使用自定义的smallicon。

我通过覆盖初始代码来快速破解

    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(getResourceId(context, "pushicon", "drawable", context.getPackageName()))
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), getResourceId(context, "icon", "drawable", context.getPackageName())))
.setWhen(System.currentTimeMillis())
.setContentTitle(extras.getString("title"))
.setTicker(extras.getString("title"))
.setContentIntent(contentIntent)
.setAutoCancel(true);

String message = extras.getString("message");
if (message != null) {
mBuilder.setContentText(message);
} else {
mBuilder.setContentText("<missing message content>");
}

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());
}

现在,您需要做的就是将名为“pushicon”的图像放入 drawable 文件夹 platforms/android/res/drawable/pushicon.png(我也让它使用图像“图标”作为大图标)

如果太麻烦的话,我为此做了一个 git repo https://github.com/zxshinxz/PushPlugin.git

cordova 插件添加 https://github.com/zxshinxz/PushPlugin.git

希望其他程序员不要经历我经历过的痛苦。

关于android - 应用程序在后台时,Cordova 本地通知不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26799936/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com