2012-10-22 75 views
2

我有一些服务器端代码,我试图创建推送通知。结果是这样的:Android谷歌云消息传递 - 推送到设备,但设备不显示推送通知

{"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); 

这里是一个与谷歌云消息交易清单的一部分:

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

}

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

+0

这里的成功意味着成功发布云邮件服务器谷歌服务器。我不认为服务器有任何方法可以知道推送消息是否已经通过。 – drulabs

+0

@KKD谢谢 - 奇怪的是,如果卷曲成功,那么我无法弄清楚为什么手机没有得到推送通知:) – Genadinik

+0

我可以想到两种可能的情况....(1)手机没有连接到互联网(我相信你检查了).........(2)你连接到的无线网络,是防火墙...... – drulabs

回答

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"); 

}

+0

那样做 - 谢谢!我只能在17个小时内奖励赏金。我会把它给你然后:) – Genadinik

+0

不客气。我很高兴它解决了! :) – nsemeniuk

1

您需要在onMessage()方法中实际手动生成通知。 onMessage()只是一个方法,当你的应用程序从服务器收到痒痒的时候会被调用。您可能并不总是希望为用户生成可见的状态栏通知。所以谷歌给了灵活性,只要你想要通知。无论如何,这里的代码将帮助您生成此通知。显然,你可以根据自己的需要调整它。

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); 
} 
+0

谢谢你,我有类似的东西,就像你建议的那样。我将我的代码添加到我的原始问题中。有没有什么我在任何机会中都没有正确执行我的代码? – Genadinik

+0

好吧,你永远不会从'onMessage()'方法调用'generateNotification()'... –

+0

谢谢 - 其他答案帮助了我,但我会通过你的一些其他问题/答案并upvote你:) – Genadinik