PubNub推送通知

时间:2016-04-18 13:56:34

标签: php android push-notification google-cloud-messaging pubnub

我计划使用PubNub通过Mobile Push Gateways发送推送通知。我的计划是为每个注册ID与之关联的用户建立一个频道。当我想发送通知时,我的PHP服务器将订阅用户的唯一频道并向其发布消息,然后从频道取消订阅。

PubNub是否支持PHP语言发布推送通知(PNmessage)?以上模型是否适用于通过PubNub发送推送通知?

1 个答案:

答案 0 :(得分:1)

您无需订阅Pubnub的推送通知。只需在用户的pubnub频道上发布消息,并在Android上为该特定频道启用推送通知。您将在收到GCM通知的同一地点收到推送通知。对于ex,通道是410。 所以在android方面,写一下

Pubnub.enablePushNotificationsForChannel("410");

在GCMListenerService中,您可以接收消息。

如果您不使用GCM,

在Android端写,

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

您可以在回调的successCallback方法中接收消息。但是你必须确保一个Pubnub实例继续运行,这在Android中很难实现。

我使用Pubnub实现了一个完整的聊天模块。当应用程序在前台时,我使用Pubnub的订阅方法而不是oush通知,因为它们更快。在后台,我取消订阅频道并启用推送通知。像这样:

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

在我的Application类中,我这样做:

Foreground.init(this).addListener(new Foreground.Listener() {
        @Override
        public void onBecameForeground() {
            PubnubWrapper.getInstance().subscribeAndDisablePushNotifications();
        }

        @Override
        public void onBecameBackground() {
                            PubnubWrapper.getInstance().unsubscribeAndEnablePushNotifications();

           }
        }
    });

是的,这是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) {}

}