Google云消息传递GCM - 未发送推送通知(服务器端)

时间:2012-10-20 18:09:27

标签: php android google-cloud-messaging

我能够获取设备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,结果发现消息正在进入设备。但是设备由于某种原因没有显示推送通知。

3 个答案:

答案 0 :(得分:3)

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

更多信息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" />

答案 1 :(得分:1)

如果您计划让您的消息覆盖该类型的上一条消息,则只需要一个collapseKey。因此,如果您要发送应用程序需要同步的消息,则可以为其提供折叠密钥,以便它只发送1条同步消息。官方docs描述了如何使用它。

答案 2 :(得分:0)

从GCM Server发送通知时,要使用哪个网址? https://android.googleapis.com/gcm/sendhttps://gcm-http.googleapis.com/gcm/send