Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCM returns a null message type

I created an application that uses GoogleCloudMessaging. Application can register to the gcm and store its registration id to the database at my server. I am using php, for sending push notifications but when the google sends it to my device, the intent service finds its message type to be null. I have tried the same code in a different application and it worked well. but this time it doesn't. The application can get the message from google and handle it by showing a notification with an empty text. I provided the intent service and php codes below. Thanks for your answers.

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

In short, "Log.v(MainActivity.TAG, "IntentService messagetype= " + messageType);" displays "IntentService messagetype= null". How can i solve this problem?

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);
}
}
like image 677
Mert Karatas Avatar asked Jan 07 '14 22:01

Mert Karatas


2 Answers

Check you AndroidManifest.xml ! And Fix settings for GCM like below. In my case, I solved this "null" problem. Good luck!

<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>
like image 200
cmcromance Avatar answered Oct 12 '22 04:10

cmcromance


In My case, I fixed it by removing:

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

It is not longer necessary according to the official guide: https://developer.android.com/google/gcm/client.html

Note, also note that exported="true" in the Receiver is not required either.

like image 36
unify Avatar answered Oct 12 '22 02:10

unify