GCM返回空消息类型

时间:2014-01-07 22:21:06

标签: android null push-notification google-cloud-messaging message-type

我创建了一个使用GoogleCloudMessaging的应用程序。应用程序可以注册到gcm并将其注册ID存储到我的服务器上的数据库。我正在使用php,用于发送推送通知,但当谷歌将其发送到我的设备时,意图服务发现其消息类型为空。我在不同的应用程序中尝试了相同的代码并且运行良好。但这一次没有。该应用程序可以从谷歌获取消息并通过显示带有空文本的通知来处理它。我在下面提供了意图服务和php代码。谢谢你的回答。

send_message.php

<?php
if (isset($_GET["regId"]) && isset($_GET["message"])) {
$regId = $_GET["regId"];
$message = $_GET["message"];

include_once './GCM.php';

$gcm = new GCM();

$registatoin_ids = array($regId);
$message = array("price" => $message);

$result = $gcm->send_notification($registatoin_ids, $message);

echo $result;
}
?>

GCM.php

<?php

class GCM {

//put your code here
// constructor
function __construct() {

}

/**
 * Sending Push Notification
 */
public function send_notification($registatoin_ids, $message) {
    // include config
    include_once './config.php';

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

    $fields = array(
        'registration_ids' => $registatoin_ids,
        'data' => $message,
    );

    $headers = array(
        'Authorization: key=' . GOOGLE_API_KEY,
        'Content-Type: application/json'
    );
    // Open connection
    $ch = curl_init();

    // Set the url, number of POST vars, POST data
    curl_setopt($ch, CURLOPT_URL, $url);

    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    // Disabling SSL Certificate support temporarly
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));

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

    // Close connection
    curl_close($ch);
    echo $result;
    }

}

?>

MyIntentService.java

public class MyIntentService extends IntentService {

public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;

public MyIntentService() {
    super("MyIntentService");
}

@Override
protected void onHandleIntent(Intent intent) {
    Log.v(MainActivity.TAG, "Handling intent.");
    Bundle extras = intent.getExtras();
    GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
    // The getMessageType() intent parameter must be the intent you received
    // in your BroadcastReceiver.
    String messageType = gcm.getMessageType(intent);
    generateNotification(getApplicationContext(), extras.getString("price"));
    Log.v(MainActivity.TAG, "IntentService messagetype= " + messageType);
    if (!extras.isEmpty()) {  // has effect of unparcelling Bundle
        /*
         * Filter messages based on message type. Since it is likely that GCM will be
         * extended in the future with new message types, just ignore any message types   
         * not interested in, or that you don't recognize.
         */
        if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
            sendNotification("Send error: " + extras.toString());
        } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
            sendNotification("Deleted messages on server: " + extras.toString());
        // If it's a regular GCM message, do some work.
        } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
            // This loop represents the service doing some work.
//                for (int i = 0; i < 5; i++) {
//                    Log.i(TAG, "Working... " + (i + 1)
//                            + "/5 @ " + SystemClock.elapsedRealtime());
//                    try {
//                        Thread.sleep(5000);
//                    } catch (InterruptedException e) {
//                    }
//                }
            Log.i(MainActivity.TAG, "Completed work @ " +SystemClock.elapsedRealtime());
            // Post notification of received message.
            sendNotification("Received: " + extras.toString());
            generateNotification(getApplicationContext(),
"Received:" + extras.getString("price"));
            Log.i(MainActivity.TAG, "Received: " + extras.toString());
        }
    }
    // Release the wake lock provided by the WakefulBroadcastReceiver.
    WakefulBroadcastReceiver.completeWakefulIntent(intent);
}

简而言之,“Log.v(MainActivity.TAG,”IntentService messagetype =“+ messageType);”显示“IntentService messagetype = null”。我该如何解决这个问题?

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    // Explicitly specify that GcmIntentService will handle the intent.
    ComponentName comp = new ComponentName(context.getPackageName(),
            GcmIntentService.class.getName());
    // Start the service, keeping the device awake while it is launching.
    startWakefulService(context, (intent.setComponent(comp)));
    setResultCode(Activity.RESULT_OK);
}
}

3 个答案:

答案 0 :(得分:4)

检查AndroidManifest.xml! 并修复GCM的设置,如下所示。 就我而言,我解决了这个“空”问题。 祝你好运!

<permission
    android:name="[MY PACKAGE NAME].permission.C2D_MESSAGE"
    android:protectionLevel="signature" />
...

<uses-permission android:name="[MY PACKAGE NAME].permission.C2D_MESSAGE" />
...
<service android:name="[MY PACKAGE NAME].GCMIntentService" /> 
...
<receiver
    android:name="[MY PACKAGE NAME].GcmBroadcastReceiver"  android:exported="true"
    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="[MY PACKAGE NAME]" />
    </intent-filter>
</receiver>

答案 1 :(得分:1)

在我的情况下,我通过删除来修复它:

<action android:name="com.google.android.c2dm.intent.REGISTRATION" />

根据官方指南,不再需要: https://developer.android.com/google/gcm/client.html

注意,还要注意export =&#34; true&#34;在接收者中也不需要。

答案 2 :(得分:-1)

我没有按照Android文档的建议检查messageType,而是检查Intent操作。这是我眼中的一项工作,但有效:

/**
 * Action for GCM registration intents.
 */
private static final String ACTION_GCM_REGISTRATION =
        "com.google.android.c2dm.intent.REGISTRATION";

/**
 * Action for new app updated installed intent.
 */
private static final String ACTION_PACKAGE_REPLACED =
        "android.intent.action.PACKAGE_REPLACED";

@Override
protected void onHandleIntent(final Intent intent) {
    final Bundle extras = intent.getExtras();
    final String action = intent.getAction();
    final GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);

    // messageType will be null for broadcasts with action registration
    // or package replaced
    String messageType = gcm.getMessageType(intent);

    if (!extras.isEmpty()) {
        if (GoogleCloudMessaging.
                MESSAGE_TYPE_MESSAGE.equals(messageType)) {
            onNotification("Received: " + extras.toString());
        } else if (action.equals(ACTION_GCM_REGISTRATION)) {
            onRegistration(extras.getString("registration_id"), intent);
        } else if (action.equals(ACTION_PACKAGE_REPLACED)) {
            onNewAppVersion();
        }
    }

    GcmBroadcastReceiver.completeWakefulIntent(intent);
}