【问题标题】:Google cloud messaging GCM - Push Notification not being sent (Server Side)谷歌云消息 GCM - 未发送推送通知(服务器端)
【发布时间】:2012-10-20 18:09:27
【问题描述】:

我能够获取设备 ID 并将其保存到我的数据库中,当发生某些事情时,我会尝试发送推送通知,但它没有发送到手机。这是我在 PHP 中所做的:

$url = 'https://android.googleapis.com/gcm/send';

$device_ids = array( $device_id );

$headers = array('Authorization: key=' . 'my_api_key',
'Content-Type: application/json');

$t_data = array();
$t_data['message'] = 'Someone commented on your business.';

$t_json = array( 'registration_ids' => $device_ids , 'data' => $t_data );

$ch = curl_init();

curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Authorization: key=my_id', 'Content-Type: application/json' ) );
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode( $t_json ) );

curl_setopt($ch, CURLOPT_URL, $url);

$result = curl_exec($ch);
if ($result === FALSE)
{
     die('Curl failed: ' . curl_error($ch));
}

curl_close($ch);

这是我从 curl_exec 调用中得到的结果:

{"multicast_id":8714083978034301091,"success":1,"failure":0,"canonical_ids":0,"r‌​esults":[{"message_id":"0:1350807053347963%9aab4bd8f9fd7ecd"}]} 

我想知道的一件事是我是否必须在应用程序中做一些额外的事情,比如编写我自己的 Reciever 类? 谢谢!

编辑:

这是我的 GCMIntentService 类:

package com.problemio;

import static com.google.android.gcm.GCMConstants.ERROR_SERVICE_NOT_AVAILABLE;
import static com.google.android.gcm.GCMConstants.EXTRA_ERROR;
import static com.google.android.gcm.GCMConstants.EXTRA_REGISTRATION_ID;
import static com.google.android.gcm.GCMConstants.EXTRA_SPECIAL_MESSAGE;
import static com.google.android.gcm.GCMConstants.EXTRA_TOTAL_DELETED;
import static com.google.android.gcm.GCMConstants.EXTRA_UNREGISTERED;
import static com.google.android.gcm.GCMConstants.INTENT_FROM_GCM_LIBRARY_RETRY;
import static com.google.android.gcm.GCMConstants.INTENT_FROM_GCM_MESSAGE;
import static com.google.android.gcm.GCMConstants.INTENT_FROM_GCM_REGISTRATION_CALLBACK;
import static com.google.android.gcm.GCMConstants.VALUE_DELETED_MESSAGES;

import java.util.Random;
import java.util.concurrent.TimeUnit;

import com.google.android.gcm.GCMBaseIntentService;

import android.app.AlarmManager;
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.SystemClock;
import android.util.Log;
import android.widget.Toast;

import utils.GCMConstants;

public class GCMIntentService extends GCMBaseIntentService 
{
    public GCMIntentService() 
    {
            super(ProblemioActivity.SENDER_ID);
    }

    @Override
      protected void onRegistered(Context ctxt, String regId) {
        Log.d(getClass().getSimpleName(), "onRegistered: " + regId);
        Toast.makeText(this, regId, Toast.LENGTH_LONG).show();
      }

      @Override
      protected void onUnregistered(Context ctxt, String regId) {
        Log.d(getClass().getSimpleName(), "onUnregistered: " + regId);
      }

      @Override
      protected void onMessage(Context ctxt, Intent message) {
        Bundle extras=message.getExtras();

        for (String key : extras.keySet()) {
          Log.d(getClass().getSimpleName(),
                String.format("onMessage: %s=%s", key,
                              extras.getString(key)));
        }
      }

      @Override
      protected void onError(Context ctxt, String errorMsg) {
        Log.d(getClass().getSimpleName(), "onError: " + errorMsg);
      }

      @Override
      protected boolean onRecoverableError(Context ctxt, String errorMsg) {
        Log.d(getClass().getSimpleName(), "onRecoverableError: " + errorMsg);

        return(true);
      } 
}

更新:

查看 LogCat,结果发现消息正在到达设备。但是设备由于某种原因没有显示推送通知。

【问题讨论】:

    标签: php android google-cloud-messaging


    【解决方案1】:

    从响应看来,消息已送达。在 Android 上,您应该有一个扩展 GCMBaseIntentService 的 GCMIntentService 类,以便在设备上接收消息。您应该检查 SDK 示例中的 gcm-demo-client 以获得有关如何在应用程序上实现此功能的好方法。您只需在 CommonUtilities 类中设置 SENDER_ID(您的 google 项目编号)即可接收来自您的服务器的消息。

    更多信息here

    要在 GCMIntentService 上生成通知,您可以使用:

     //Issues a notification to inform the user that server has sent a message.
    
    private static void generateNotification(Context context, String message, String title,) {
    
            int icon = R.drawable.logo;
    
            NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    
            Intent notificationIntent = new Intent(context, AnActivity.class);
    
            // set intent so it does not start a new activity
            notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
            PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0);        
            Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);            
    
             Notification notification = new NotificationCompat.Builder(context)
             .setContentTitle(title)
             .setContentText(message)
             .setContentIntent(intent)
             .setSmallIcon(icon)
             .setLights(Color.YELLOW, 1, 2)
             .setAutoCancel(true)
             .setSound(defaultSound)
             .build();
    
            notificationManager.notify(0, notification);
    }
    

    您是否还在清单上注册了接收方?在应用标签下?

        <!--
          BroadcastReceiver that will receive intents from GCM
          services and handle them to the custom IntentService.
    
          The com.google.android.c2dm.permission.SEND permission is necessary
          so only GCM services can send data messages for the app.
        -->
        <receiver
            android:name="com.google.android.gcm.GCMBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>
                <!-- Receives the actual messages. -->
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <!-- Receives the registration id. -->
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
                <category android:name="com.google.android.gcm.demo.app" />
            </intent-filter>
        </receiver>
    
        <!--
          Application-specific subclass of GCMBaseIntentService that will
          handle received messages.
    
          By default, it must be named .GCMIntentService, unless the
          application uses a custom BroadcastReceiver that redefines its name.
        -->
        <service android:name=".GCMIntentService" />
    

    【讨论】:

    • 我刚刚发布了我的 GCMIntentService 但我不确定如何调整它以创建推送通知。
    • 您在日志中看不到这个? Log.d(getClass().getSimpleName(), String.format("onMessage: %s=%s", key, extras.getString(key)));
    • 那么问题是我的 GCMIntentService 中没有 generateNotification() 方法吗?
    • 如果您看到的是日志,而不是通知,那么您需要该方法来创建一个。
    • 实际上我正在设备上进行测试,所以我不确定如何从设备中检查日志:)
    【解决方案2】:

    如果您打算让您的消息覆盖该类型的先前消息,则只需要一个 collapseKey。因此,如果您要发送应用程序需要同步的消息,您可以给它一个折叠键,这样它只会发送 1 条同步消息。官方docs描述如何使用。

    【讨论】:

    • 是的,但您知道为什么没有创建推送吗?
    • 你确定它没有被创建吗?或者它只是没有显示在设备上 - 这可能是由几个不同的问题引起的
    • 实际上我只知道它不会进入设备。如何判断它是否正在生成但未显示在设备上?
    • 你应该得到某种回应。它会告诉您您的请求是否有问题,或者他们是否找不到注册 ID 等。您会得到什么响应?
    • 这是来自服务器的结果:{"multicast_id":8714083978034301091,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id" :"0:1350807053347963%9aab4bd8f9fd7ecd"}]}
    【解决方案3】:

    从 GCM 服务器发送通知时,要使用哪个 url? https://android.googleapis.com/gcm/sendhttps://gcm-http.googleapis.com/gcm/send

    【讨论】:

      猜你喜欢
      • 2015-03-08
      • 1970-01-01
      • 1970-01-01
      • 2014-01-08
      • 1970-01-01
      • 2015-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多