Muhammad Ashraf
Muhammad Ashraf

Reputation: 1282

Sending Push Notification From QuickBlox in Android

I've used the quickblox chat sample and it worked fine, But I wanted to use push notifications in it.. So I followed some tutorials and read the sample and just done like it.. But when I push notification from QuickBlox Admin Panel: Messages no thing happens in my application.. No Logs, No Notifications.. No Thing..!

I'm sure that the project number and api key are correct..

Here's the manifest :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.quickblox.sample.chat"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="10"
    android:targetSdkVersion="19" />

<permission
    android:name="com.quickblox.sample.chat.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />

<uses-permission android:name="com.quickblox.sample.chat.permission.C2D_MESSAGE" />

<!-- 5. Add the following permissions: -->
<!-- App receives GCM messages. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- GCM connects to Google Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 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" />
<!-- Access to  device info -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

<application
    android:name=".ApplicationSingleton"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".ui.activities.SplashActivity"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:label="@string/app_name"
        android:screenOrientation="portrait" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".ui.activities.NewDialogActivity"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:screenOrientation="portrait" />
    <activity
        android:name="com.quickblox.sample.chat.DialogsActivity"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:screenOrientation="portrait" />
    <activity
        android:name=".ui.activities.ChatActivity"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="adjustResize" />

    <receiver
        android:name=".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.quickblox.sample.chat" />
        </intent-filter>
    </receiver>

    <!-- 2. Add the following intent service: -->
    <service android:name=".GCMIntentService" />

    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />
</application>
</manifest>

GcmBroadcastReceiver :

package com.quickblox.sample.chat;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;

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.
    Log.d("Login", "Receiver - Received Message!");
    startWakefulService(context, (intent.setComponent(comp)));
    setResultCode(Activity.RESULT_OK);
}
}

GCMIntentService :

package com.quickblox.sample.chat;

import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;

import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.quickblox.sample.chat.definitions.Consts;

public class GCMIntentService extends IntentService {

public static final int NOTIFICATION_ID = 1;

private static final String TAG = GCMIntentService.class.getSimpleName();

private NotificationManager notificationManager;

public GCMIntentService() {
    super(Consts.GCM_INTENT_SERVICE);
}

@Override
protected void onHandleIntent(Intent intent) {
    Log.i(TAG, "new push");

    Bundle extras = intent.getExtras();
    GoogleCloudMessaging googleCloudMessaging = GoogleCloudMessaging.getInstance(this);
    // The getMessageType() intent parameter must be the intent you received
    // in your BroadcastReceiver.
    String messageType = googleCloudMessaging.getMessageType(intent);

    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 you're not interested in, or that you don't
         * recognize.
         */
       if (GoogleCloudMessaging.
                MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
            processNotification(Consts.GCM_SEND_ERROR, extras);
        } else if (GoogleCloudMessaging.
                MESSAGE_TYPE_DELETED.equals(messageType)) {
            processNotification(Consts.GCM_DELETED_MESSAGE, extras);
            // If it's a regular GCM message, do some work.
        } else if (GoogleCloudMessaging.
                MESSAGE_TYPE_MESSAGE.equals(messageType)) {
            // Post notification of received message.
            processNotification(Consts.GCM_RECEIVED, extras);
            Log.i(TAG, "Received: " + extras.toString());
        }
    }
    // Release the wake lock provided by the WakefulBroadcastReceiver.
    WakefulBroadcastReceiver.completeWakefulIntent(intent);
}

// Put the message into a notification and post it.
// This is just one simple example of what you might choose to do with
// a GCM message.
private void processNotification(String type, Bundle extras) {
    notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    final String messageValue = extras.getString("message");

    Intent intent = new Intent(this, DialogsActivity.class);
    intent.putExtra(Consts.EXTRA_MESSAGE, messageValue);

    PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
            intent, 0);

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
            this)
            .setSmallIcon(R.drawable.ic_launcher)
            .setContentTitle(Consts.GCM_NOTIFICATION)
            .setStyle(
                    new NotificationCompat.BigTextStyle()
                            .bigText(messageValue))
            .setContentText(messageValue);

    mBuilder.setContentIntent(contentIntent);
    notificationManager.notify(NOTIFICATION_ID, mBuilder.build());


}
}

I have the following code for registration in activity :

    gcm = GoogleCloudMessaging.getInstance(this);

    regId = getRegisterationId(this);
    Log.d("Login", "ID: " + regId);
    if (regId.isEmpty()) {
        new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    if (gcm == null) {
                        gcm = GoogleCloudMessaging.getInstance(DialogsActivity.this);
                    }

                    regId = gcm.register(Consts.PROJECT_NUMBER);
                    Log.d("Login", "Registered! ID: " + regId);

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            subscribeToPushNotifications(regId);
                        }
                    });


                } catch (Exception e) {
                    Log.d("Login", "Reg e: " + e);
                }
            }
        }).start();
    } else {
        Log.d("Login", "Already Exist");
        subscribeToPushNotifications(regId);
    }       gcm = GoogleCloudMessaging.getInstance(this);

    regId = getRegisterationId(this);
    Log.d("Login", "ID: " + regId);
    if (regId.isEmpty()) {
        new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    if (gcm == null) {
                        gcm = GoogleCloudMessaging.getInstance(DialogsActivity.this);
                    }

                    regId = gcm.register(Consts.PROJECT_NUMBER);
                    Log.d("Login", "Registered! ID: " + regId);

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            subscribeToPushNotifications(regId);
                        }
                    });


                } catch (Exception e) {
                    Log.d("Login", "Reg e: " + e);
                }
            }
        }).start();
    } else {
        Log.d("Login", "Already Exist");
        subscribeToPushNotifications(regId);
    }

public void subscribeToPushNotifications(String regId) {
    String deviceId = ((TelephonyManager) getBaseContext()
            .getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();

    QBMessages.subscribeToPushNotificationsTask(regId, deviceId,
            QBEnvironment.DEVELOPMENT,
            new QBEntityCallbackImpl<ArrayList<QBSubscription>>() {
                @Override
                public void onSuccess(ArrayList<QBSubscription> result,
                        Bundle params) {
                    Log.d("Login", "Successfully Registered");
                }

                @Override
                public void onError(List<String> errors) {
                    Log.d("Login", "e : " + errors);
                }
            });

}

private String getRegisterationId(Context context) {
    SharedPreferences prefs = getGCMPreferences(context);
    String registerationId = prefs.getString(PROPERTY_REG_ID, "");
    if (registerationId.isEmpty()) {
        Log.d("Login", "Not registered!");
        return "";
    }
    return registerationId;

}

private SharedPreferences getGCMPreferences(Context context) {
    return getSharedPreferences(DialogsActivity.class.getSimpleName(),
            Context.MODE_PRIVATE);
}

private void storeRegisterationId(Context context, String regId) {
    final SharedPreferences prefs = getGCMPreferences(context);
    SharedPreferences.Editor editor = prefs.edit();
    editor.putString(PROPERTY_REG_ID, regId);
    editor.commit();
}

And I get that registration done successfully.. :S

I've been searching for the solution for 2 days now :/ Any help will be appreciated.. Thanks.

Upvotes: 0

Views: 2222

Answers (1)

cjkennedyo
cjkennedyo

Reputation: 33

I don't have enough reputation to comment, so I am putting this as a possible answer -

I have been working through the same for the last couple of days, and here are a couple of things to check:

  1. When you set up the GCM API key, did you set any IPs? You should leave this blank to accept all.

  2. When you say the registration is done successfully, do you mean you get the onSuccess Log message from subscribeToPushNotificationsTask? Check your device id; I was getting null for deviceId from:

String deviceId = ((TelephonyManager)getBaseContext().getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();

So instead I had to use

String deviceId = Secure.getString(this.getContentResolver(), Secure.ANDROID_ID);
  1. What options were you selecting in the Quickblox Admin Panel > Messages? Be sure you are selecting "GCM (Android Push)" under the channel option.

  2. Lastly, make sure you are using all production or all development for your environments (QBEnvironment.DEVELOPMENT). I somehow ended up with a mix, and switched them all to production now.

My push notifications are now working, so perhaps I can help out more if you have specific questions.

Upvotes: 1

Related Questions