I am planing to use PubNub to send push notification through Mobile Push Gateways. My plan is to have a channel for each user where registration id is associated to it. And when I want to send a notification my PHP server will subscribe to the user's unique channel and publish a message to it then unsubscribe form the channel.
Does PubNub support PHP language to publish push notification (PNmessage)? Is the above model valid for sending push notification through PubNub?
You don't need to subscribe for Pubnub's push notification. Just publish the message on user's pubnub channel and enable push notification on Android for that particular channel. You will receive the push notification at the same place where you receive GCM notifications. For ex let the channel is 410. So on android side, write
Pubnub.enablePushNotificationsForChannel("410");
Inside your GCMListenerService you can receive messages.
In case you are not using GCM,
On Android side write,
public void subscribe() {
String[] channels = {PrefUtils.getUserId(context) + "", ChatUtils.getDeliveryChannel(PrefUtils.getUserId(context)), ChatUtils.getReadChannel(PrefUtils.getUserId(context))};
try {
this.getPubnubInstance().subscribe(channels, new Callback() {
@Override
public void successCallback(String channel, Object message) {
super.successCallback(channel, message);
if (PubnubWrapper.this.onPubnubMessageReceiveListener != null)
PubnubWrapper.this.onPubnubMessageReceiveListener.onMessageReceived(channel, message);
}
@Override
public void connectCallback(String channel, Object message) {
super.connectCallback(channel, message);
}
@Override
public void reconnectCallback(String channel, Object message) {
super.reconnectCallback(channel, message);
}
@Override
public void disconnectCallback(String channel, Object message) {
super.disconnectCallback(channel, message);
}
@Override
public void errorCallback(String channel, PubnubError error) {
super.errorCallback(channel, error);
}
});
} catch (PubnubException e) {
e.printStackTrace();
}
}
You can receive message inside the callbacks's successCallback method. But you have to make sure that a Pubnub instance keeps running, which is painful to do in Android.
I have implemented a full fledged Chat Module using Pubnub. When app is in foreground I use Pubnub's subscribe method and not oush notifications as they are faster. While in background, I unsubscribe from channels and enable push notifications. Like this:
public void subscribeAndDisablePush(String gcm_token) {
String[] channels = {PrefUtils.getUserId(context) + "", ChatUtils.getDeliveryChannel(PrefUtils.getUserId(context)), ChatUtils.getReadChannel(PrefUtils.getUserId(context))};
getPubnubInstance().disablePushNotificationsOnChannels(channels, gcm_token);
try {
getPubnubInstance().subscribe(channels, new Callback() {
@Override
public void successCallback(String channel, Object message) {
super.successCallback(channel, message);
}
});
} catch (PubnubException e) {
e.printStackTrace();
}
}
public void unsubscribeAndEnablePush(String gcm_token) {
String[] channels = {PrefUtils.getUserId(context) + "", ChatUtils.getDeliveryChannel(PrefUtils.getUserId(context)), ChatUtils.getReadChannel(PrefUtils.getUserId(context))};
getPubnubInstance().enablePushNotificationsOnChannels(channels, gcm_token, new Callback() {
@Override
public void successCallback(String channel, Object message) {
super.successCallback(channel, message);
Log.e("Subscribed", "YES");
}
@Override
public void errorCallback(String channel, PubnubError error) {
super.errorCallback(channel, error);
Log.e("Subscribed", "No");
}
});
getPubnubInstance().unsubscribe(channels);
}
Inside My Application class I do this:
Foreground.init(this).addListener(new Foreground.Listener() {
@Override
public void onBecameForeground() {
PubnubWrapper.getInstance().subscribeAndDisablePushNotifications();
}
@Override
public void onBecameBackground() {
PubnubWrapper.getInstance().unsubscribeAndEnablePushNotifications();
}
}
});
And yes this is Foreground.java:
public class Foreground implements Application.ActivityLifecycleCallbacks {
public static final long CHECK_DELAY = 500;
public static final String TAG = Foreground.class.getName();
public interface Listener {
public void onBecameForeground();
public void onBecameBackground();
}
private static Foreground instance;
private boolean foreground = false, paused = true;
private Handler handler = new Handler();
private List<Listener> listeners = new CopyOnWriteArrayList<Listener>();
private Runnable check;
/**
* Its not strictly necessary to use this method - _usually_ invoking
* get with a Context gives us a path to retrieve the Application and
* initialise, but sometimes (e.g. in test harness) the ApplicationContext
* is != the Application, and the docs make no guarantees.
*
* @param application
* @return an initialised Foreground instance
*/
public static Foreground init(Application application){
if (instance == null) {
instance = new Foreground();
application.registerActivityLifecycleCallbacks(instance);
}
return instance;
}
public static Foreground get(Application application){
if (instance == null) {
init(application);
}
return instance;
}
public static Foreground get(Context ctx){
if (instance == null) {
Context appCtx = ctx.getApplicationContext();
if (appCtx instanceof Application) {
init((Application)appCtx);
}
throw new IllegalStateException(
"Foreground is not initialised and " +
"cannot obtain the Application object");
}
return instance;
}
public static Foreground get(){
if (instance == null) {
throw new IllegalStateException(
"Foreground is not initialised - invoke " +
"at least once with parameterised init/get");
}
return instance;
}
public boolean isForeground(){
return foreground;
}
public boolean isBackground(){
return !foreground;
}
public void addListener(Listener listener){
listeners.add(listener);
}
public void removeListener(Listener listener){
listeners.remove(listener);
}
@Override
public void onActivityResumed(Activity activity) {
paused = false;
boolean wasBackground = !foreground;
foreground = true;
if (check != null)
handler.removeCallbacks(check);
if (wasBackground){
Log.i(TAG, "went foreground");
for (Listener l : listeners) {
try {
l.onBecameForeground();
} catch (Exception exc) {
Log.e(TAG, "Listener threw exception!", exc);
}
}
} else {
Log.i(TAG, "still foreground");
}
}
@Override
public void onActivityPaused(Activity activity) {
paused = true;
if (check != null)
handler.removeCallbacks(check);
handler.postDelayed(check = new Runnable(){
@Override
public void run() {
if (foreground && paused) {
foreground = false;
Log.i(TAG, "went background");
for (Listener l : listeners) {
try {
l.onBecameBackground();
} catch (Exception exc) {
Log.e(TAG, "Listener threw exception!", exc);
}
}
} else {
Log.i(TAG, "still foreground");
}
}
}, CHECK_DELAY);
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}
@Override
public void onActivityStarted(Activity activity) {}
@Override
public void onActivityStopped(Activity activity) {}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
@Override
public void onActivityDestroyed(Activity activity) {}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With