Parse.com推送通知在后台没有显示在Android上 [英] Parse.com push notifications not shown in background on android

查看:164
本文介绍了Parse.com推送通知在后台没有显示在Android上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Parse.com与Ionic应用程式和PushPlugin,并尝试透过GCM使用自订的寄件者ID来导入Parse的推送通知。



m向所有设备发送消息或使用带有cURL的REST API
当应用程序在后台但iOS通知不可用时,iOS通知触发正常。



这里是我尝试与其余的API第一为iOS,这是工作很好:

  curl -X POST \ 
-HX-Parse-Application-Id:APP-ID\
-HX-Parse-REST-API-Key:API-KEY\
-H Content-Type:application / json\
-d'{
where:{
deviceType:ios
},
:{
alert:Hello World!
}
}'\
https://api.parse.com/1/push

即使应用程序在后台关闭或打开,iOS也会收到并显示通知。



现在,定位到Android设备:

  curl -X POST \ 
-HX-Parse-Application-Id: APP-ID\
-HX-Parse-REST-API-Key:API-KEY\
-HContent-Type:application / json\
-d'{
where:{
deviceType:android
},
data:{
alert:Hello World !
}
}'\
https://api.parse.com/1/push

通知由设备接收并部分登录在 adb logcat 中,但不会显示在通知栏中或以其他方式确认。我尝试将'alert'更改为'message',但没有效果。



但是,如果我尝试使用GCM HTTP API与Postman或cURL,一切都很好:

  curl'https://android.googleapis.com/gcm/send'\ 
-H'authorization:key = API-KEY'\
-H'content-type:application / json '\
-d'{
registration_ids:[
DEVICE-REGISTRATION-ID
],
data:{
message:你走我去,伙计!
}
}'

记录 adb logcat 使用GCM API和Parse推送通知API时的日志不同:



使用Parse:

  I / GCM(10319):GCM message co.yougoigo.mobile 0:1423318254669687%bd9ff524f9fd7ecd 
V / GCMBroadcastReceiver(11506):onReceive:com.google。 android.c2dm.intent.RECEIVE
V / GCMBroadcastReceiver(11506):GCM IntentService类:com.plugin.gcm.GCMIntentService
V / GCMBaseIntentService(11506):获取wakelock
V / GCMBaseIntentService 11506):Intent服务名称:GCMIntentService-GCMIntentService-3
D / GCMIntentService(11506):onMessage - 上下文:android.app.Application@251ee33b

使用GCM cURL调用:

  I / GCM GCM消息co.yougoigo.mobile 0:1423318321652064%bd9ff524f9fd7ecd 
I / ActivityManager(745):启动proc co.yougoigo.mobile的广播co.yougoigo.mobile/com.plugin.gcm.CordovaGCMBroadcastReceiver:pid = 11788 uid = 10187 gids = {50187,9997,3003} abi = armeabi-v7a
V / GCMBroadcastReceiver(11788):onReceive:com.google.android.c2dm.intent.RECEIVE
V / GCMRegistrar :将重试接收器类的名称设置为com.plugin.gcm.CordovaGCMBroadcastReceiver
V / GCMBroadcastReceiver(11788):GCM IntentService类:com.plugin.gcm.GCMIntentService
V / GCMBaseIntentService(11788):获取wakelock
V / GCMBaseIntentService(11788):Intent服务名称:GCMIntentService-GCMIntentService-1
D / GCMIntentService(11788):onMessage - 上下文:android.app.Application@251ee33b
E / GCMIntentService (11788):数字格式异常 - 解析错误通知ID:无效int:null
V / GCMBaseIntentService(11788):释放唤醒锁

当前清单如下:

 <?xml version ='1.0 'encoding ='utf-8'?> 
< manifest android:hardwareAccelerated =trueandroid:versionCode =4android:versionName =0.0.4package =co.yougoigo.mobilexmlns:android =http: android.com/apk/res/android\">
< supports-screens android:anyDensity =trueandroid:largeScreens =trueandroid:normalScreens =trueandroid:resizeable =trueandroid:smallScreens =trueandroid:xlargeScreens = />
< uses-permission android:name =android.permission.INTERNET/>
< application android:hardwareAccelerated =trueandroid:icon =@ drawable / iconandroid:label =@ string / app_name>
< activity android:configChanges =orientation | keyboardHidden | keyboard | screenSize | localeandroid:label =@ string / activity_nameandroid:launchMode =singleTopandroid:name =CordovaAppandroid:theme = @android:style / Theme.Black.NoTitleBarandroid:windowSoftInputMode =adjustResize>
< intent-filter android:label =@ string / launcher_name>
< action android:name =android.intent.action.MAIN/>
< category android:name =android.intent.category.LAUNCHER/>
< / intent-filter>
< / activity>
< activity android:exported =trueandroid:name =com.plugin.gcm.PushHandlerActivity/>
< receiver android:name =com.plugin.gcm.CordovaGCMBroadcastReceiverandroid:permission =com.google.android.c2dm.permission.SEND>
< intent-filter>
< action android:name =com.google.android.c2dm.intent.RECEIVE/>
< action android:name =com.google.android.c2dm.intent.REGISTRATION/>
< category android:name =co.yougoigo.mobile/>
< / intent-filter>
< / receiver>
< service android:name =com.plugin.gcm.GCMIntentService/>
< meta-data android:name =com.facebook.sdk.ApplicationIdandroid:value =@ string / fb_app_id/>
< activity android:label =@ string / fb_app_nameandroid:name =com.facebook.LoginActivityandroid:theme =@ android:style / Theme.Translucent.NoTitleBar/&
< / application>
< uses-sdk android:minSdkVersion =10android:targetSdkVersion =19/>
< uses-permission android:name =android.permission.ACCESS_NETWORK_STATE/>
< uses-permission android:name =android.permission.GET_ACCOUNTS/>
< uses-permission android:name =android.permission.WAKE_LOCK/>
< uses-permission android:name =android.permission.VIBRATE/>
< uses-permission android:name =com.google.android.c2dm.permission.RECEIVE/>
< permission android:name =co.yougoigo.mobile.permission.C2D_MESSAGEandroid:protectionLevel =signature/>
< uses-permission android:name =co.yougoigo.mobile.permission.C2D_MESSAGE/>
< / manifest>

有没有人在获取GCM通知在phonegap应用程序上工作的经验?

解决方案

为了使用phonegap / cordova PushPlugin与Parse推你必须实现Parse实际上以非标准的方式包装它的内容。这导致PushPlugin在应用处于前台时接收推送通知,而不是当它在后台时接收推送通知。



源自GCMIntentService.java的源代码片段

  @Override 
protected void onMessage(Context context,Intent intent){
Log.d(TAG,onMessage - context:+ context);

//从消息中提取有效负载
Bundle extras = intent.getExtras();
if(extras!= null)
{
//如果我们在前台,只是表面的有效负载,否则发布到状态栏
if(PushPlugin.isInForeground )){
extras.putBoolean(foreground,true);
PushPlugin.sendExtras(extras);
}
else {
extras.putBoolean(foreground,false);

//如果有消息,发送通知
if(extras.getString(message)!= null&& extras.getString(message)。 )!= 0){
createNotification(context,extras);
}
}
}
}

你可以看到当 PushPlugin.isInForeground()的检查失败时,它会检查extras包上的message属性。



2观察结果:


  1. 解析不会在通知,因此PushPlugin不会调用 createNotification(content,extras)


这里是通过一个对象使用data来包装它比传统的GCM通知深一层JSON中包的外观如何

  {... 
payload:{
data :{
message:您的消息在这里,
title:您的标题在这里,
...,
customData:{.. 。}
}
}

逻辑从包中提取有效负载 extras.getString(payload),然后创建一个新的JSONObject(文档: http://developer.android.com/reference/org/json/JSONObject.html )。



您需要检查是否存在有效负载,而不是检查 bundle.getString(message) .data,然后解析出消息和标题,并确保它们在createNotification函数的正确位置,以便通过重新打包软件包(或创建自己的软件包)来工作。



我的建议是保留现有的代码,但是单独检查解析格式的通知并调用自定义的createNotification函数。



如:

  if(PushPlugin.isInForeground()) {
extras.putBoolean(foreground,true);
PushPlugin.sendExtras(extras);
} else if(extras.getString(message)&& amp; extras.getString(message)length()!= 0){
extras.putBoolean );
createNotification(context,extras);
} else {
JSONObject payload = extras.getString(payload);
JSONObject data = payload.getJSONObject(data);
String message = data.getString(alert)//如果不使用自定义json负载,parse会将消息作为警报。
extras.putString(message,alert)
createNotification(context,extras)
}

希望这有助于。老实说,我希望parse只是像其他人一样发送数据,以便它与PushPlugin开箱兼容。



PushPlugin的源代码GCMIntentService.java在这里找到(官方github库): https://github.com/phonegap-build/PushPlugin/blob/master/src/android/com/plugin/gcm /GCMIntentService.java


I'm using Parse.com with an Ionic app and the PushPlugin and trying to implement Parse's Push Notifications through GCM with a custom Sender ID.

When I'm sending a message to all devices, or using the REST API with cURL, iOS notifications trigger fine when the app is in the background but android notifications are not.

Here's what I tried with the rest API First for iOS, which is working well:

curl -X POST \
  -H "X-Parse-Application-Id: APP-ID" \
  -H "X-Parse-REST-API-Key: API-KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "where": {
          "deviceType": "ios"
        },
        "data": {
          "alert": "Hello World!"
        }
      }' \
  https://api.parse.com/1/push

The iOS notification is received and displayed even when the app is closed or open in the background.

Now, when I try the same targeting for android devices:

curl -X POST \
  -H "X-Parse-Application-Id: APP-ID" \
  -H "X-Parse-REST-API-Key: API-KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "where": {
          "deviceType": "android"
        },
        "data": {
          "alert": "Hello World!"
        }
      }' \
  https://api.parse.com/1/push

The notification is received by the device and partially logged in adb logcat but is not displayed in the notification bar or otherwise acknowledged. I tried changing 'alert' to 'message' but that had no effect.

However, if I try to use the GCM HTTP API with Postman or cURL, everything works well:

curl 'https://android.googleapis.com/gcm/send' \
  -H 'authorization: key=API-KEY' \
  -H 'content-type: application/json' \
  -d '{
        "registration_ids" : [
          "DEVICE-REGISTRATION-ID"
        ],
        "data" : {
          "message": "You Go I Go, Buddy!"
        }
      }'

When logging adb logcat the logs are different when using the GCM API and Parse's Push Notifications API:

With Parse:

I/GCM     (10319): GCM message co.yougoigo.mobile 0:1423318254669687%bd9ff524f9fd7ecd
V/GCMBroadcastReceiver(11506): onReceive: com.google.android.c2dm.intent.RECEIVE
V/GCMBroadcastReceiver(11506): GCM IntentService class: com.plugin.gcm.GCMIntentService
V/GCMBaseIntentService(11506): Acquiring wakelock
V/GCMBaseIntentService(11506): Intent service name: GCMIntentService-GCMIntentService-3
D/GCMIntentService(11506): onMessage - context: android.app.Application@251ee33b

And with GCM cURL call:

I/GCM     (10319): GCM message co.yougoigo.mobile 0:1423318321652064%bd9ff524f9fd7ecd
I/ActivityManager(  745): Start proc co.yougoigo.mobile for broadcast co.yougoigo.mobile/com.plugin.gcm.CordovaGCMBroadcastReceiver: pid=11788 uid=10187 gids={50187, 9997, 3003} abi=armeabi-v7a
V/GCMBroadcastReceiver(11788): onReceive: com.google.android.c2dm.intent.RECEIVE
V/GCMRegistrar(11788): Setting the name of retry receiver class to com.plugin.gcm.CordovaGCMBroadcastReceiver
V/GCMBroadcastReceiver(11788): GCM IntentService class: com.plugin.gcm.GCMIntentService
V/GCMBaseIntentService(11788): Acquiring wakelock
V/GCMBaseIntentService(11788): Intent service name: GCMIntentService-GCMIntentService-1
D/GCMIntentService(11788): onMessage - context: android.app.Application@251ee33b
E/GCMIntentService(11788): Number format exception - Error parsing Notification ID: Invalid int: "null"
V/GCMBaseIntentService(11788): Releasing wakelock

The current manifest is as follows:

<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="4" android:versionName="0.0.4" package="co.yougoigo.mobile" xmlns:android="http://schemas.android.com/apk/res/android">
    <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
    <uses-permission android:name="android.permission.INTERNET" />
    <application android:hardwareAccelerated="true" android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/activity_name" android:launchMode="singleTop" android:name="CordovaApp" android:theme="@android:style/Theme.Black.NoTitleBar" android:windowSoftInputMode="adjustResize">
            <intent-filter android:label="@string/launcher_name">
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:exported="true" android:name="com.plugin.gcm.PushHandlerActivity" />
        <receiver android:name="com.plugin.gcm.CordovaGCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
                <category android:name="co.yougoigo.mobile" />
            </intent-filter>
        </receiver>
        <service android:name="com.plugin.gcm.GCMIntentService" />
        <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/fb_app_id" />
        <activity android:label="@string/fb_app_name" android:name="com.facebook.LoginActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" />
    </application>
    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="19" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <permission android:name="co.yougoigo.mobile.permission.C2D_MESSAGE" android:protectionLevel="signature" />
    <uses-permission android:name="co.yougoigo.mobile.permission.C2D_MESSAGE" />
</manifest>

Does anyone have any experience in getting GCM notifications to work on phonegap apps?

解决方案

In order to use the phonegap/cordova PushPlugin with Parse Push you have to make the realization that Parse actually wraps it's content in a non standard way. This results in PushPlugin receiving the push notification when the app is in the foreground, but not when it is in the background.

Source code snippet from GCMIntentService.java

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

As you can see when the check for PushPlugin.isInForeground() fails it checks for a 'message' property on the extras bundle.

2 Observations:

  1. Parse does not include a 'message' on the notification so the PushPlugin doesn't call createNotification(content, extras)
  2. If you look at the 'payload' property of the bundle it also wraps it one layer deeper than "traditional" GCM notifications by putting the notification an object with the key 'data'.

Here's what the bundle looks like in JSON

{ ...
  "payload" : {
    "data" : { 
      "message" : "your message here",
      "title": "your title here",
      ...,
      "customData": { ... }
    }
}

You, therefore, have to do some custom logic to extract the payload from the bundle extras.getString("payload") and then create a new JSONObject (documentation here: http://developer.android.com/reference/org/json/JSONObject.html).

Instead of check bundle.getString("message") you need to check for check for the existence of payload.data and then parse out message and title and make sure they are in the correct locations for the createNotification function to work by repackaging the bundle (or creating your own).

My recommendation is to leave the existing code as is, but make a separate check for the parse formatted notification and call a custom createNotification function.

As in:

if (PushPlugin.isInForeground()) {
  extras.putBoolean("foreground", true);
  PushPlugin.sendExtras(extras);
} else if (extras.getString("message") && extras.getString("message").length() != 0) {
  extras.putBoolean("foreground", false);
  createNotification(context, extras);
} else {
  JSONObject payload = extras.getString("payload");
  JSONObject data = payload.getJSONObject("data");
  String message = data.getString("alert") //parse puts the message as an alert if you don't use custom json payload
  extras.putString("message", alert)
  createNotification(context, extras)
}

Hopefully this helps. Honestly, I wish parse just sent the data like everyone else so that it was compatible with PushPlugin out of the box.

Source code for PushPlugin GCMIntentService.java found here (official github repo): https://github.com/phonegap-build/PushPlugin/blob/master/src/android/com/plugin/gcm/GCMIntentService.java

这篇关于Parse.com推送通知在后台没有显示在Android上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆