Android Google Cloud Messaging - 推送到设备,但设备不显示推送通知

时间:2012-10-22 02:31:31

标签: php android curl google-cloud-messaging

我有一些服务器端代码,我正在尝试创建推送通知。结果如下:

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

这是我用来发送推送通知的PHP代码。顺便说一下,推动没有发生,所以我试图找出原因:

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

$device_ids = array( $device_id );

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

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

// Open connection
$ch = curl_init();

curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Authorization: key=my_key', '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);

// Execute post
$result = curl_exec($ch);    

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

// Close connection
curl_close($ch);

以下是处理Google云消息传递的清单部分:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.problemio"
    android:versionCode="82"
    android:versionName="2.2.82" >

    <supports-screens  android:largeScreens="true"   android:normalScreens="true"  android:smallScreens="true"/> 

    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16"/>
    <!-- <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="xx"/>  -->

    <uses-permission android:name="android.permission.INTERNET" />

    <!-- Required permission to use in-app billing. -->
    <uses-permission android:name="com.android.vending.BILLING" />



    <permission android:name="com.problemio.permission.C2D_MESSAGE" 
        android:protectionLevel="signature" />
    <uses-permission android:name="com.problemio.permission.C2D_MESSAGE" />


    <!-- App receives GCM messages. -->
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> 
    <!-- GCM requires a Google account. -->
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <!-- Keeps the processor from sleeping when a message is received. -->
    <uses-permission android:name="android.permission.WAKE_LOCK" /> 







    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" 
        android:theme="@style/CustomTheme" 
        android:name="MyApplication"
        android:debuggable="true"
                >

        <!--  For Google Cloud Messaging -->
        <receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" 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="com.problemio" />
          </intent-filter>
        </receiver>   

        <service android:name=".GCMIntentService" />
        <!--  End of Google Cloud Messaging -->

编辑:

这是我的整个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.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
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);
  } 

  private static void generateNotification(Context context, String message, String title ) 
  {
        int icon = R.drawable.ic_launcher;
        long when = System.currentTimeMillis(); // can change this to a future time if desired

        NotificationManager notificationManager = 
                (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        Intent notificationIntent = new Intent(context, ProblemioActivity.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);
}     

}

但无论我尝试什么,推送通知都不会出现在物理设备上。任何想法为什么不以及如何让它出现在设备上?

2 个答案:

答案 0 :(得分:2)

您只需要向onMessage()添加对通知函数的调用,如下所示:

@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)));
    }
    generateNotification(ctxt, extras.getString("message"), "test title");

}

答案 1 :(得分:1)

您需要在onMessage()方法中实际手动生成通知。 onMessage()只是一个方法,当你的应用程序收到来自服务器的痒痒声时将调用该方法。您可能并不总是希望向用户生成可见的状态栏通知。因此,Google可以灵活地根据需要发出通知。无论如何,这里的代码将帮助您生成此通知。显然,你可以根据自己的需要调整它。

private void generateNotification(Context context, String message)
{
    // put an icon for your notification in your res/drawable folder
    // and then get the icon as an int
    int icon = R.drawable.notif_icon_name;
    long when = System.currentTimeMillis(); // can change this to a future time if desired
    NotificationManager notificationManager = (NotificationManager) context
         .getSystemService(Context.NOTIFICATION_SERVICE);
    Notification notification = new Notification(icon, message, when);
    String title = context.getString(R.string.app_name);
    Intent notificationIntent = new Intent(context, BaseActivity.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);
    notification.setLatestEventInfo(context, title, message, intent);
    notification.flags |= Notification.FLAG_AUTO_CANCEL;
    notification.defaults |= Notification.DEFAULT_SOUND;
    notificationManager.notify(0, notification);
}