4

What is the minimum required code to establish a PubNub subscription in a service class? The examples on PubNub include code for on boot subscriptions, broadcast receivers, pushalarms, etc. Am I to believe that all this code from github is the minimum required?

The reason I ask is because I am self-learning code and having a rather rough time implementing services such as PubNub because their documentations are for a level of programmer that I haven't reached yet.

I look at the examples and try to extract just the very basic, bare necessities but I am unsure of what can be stripped from those example classes.

Thank you to someone who understands what I am trying to ask.

EDIT: To be clear this is my current PubNub service class:

public class PubNubService extends Service {

SharedPreferences sP;

static final String pub_key = " - ";
static final String sub_key = " - ";
Pubnub pubnub = new Pubnub(pub_key, sub_key, false);

String channel;
PowerManager.WakeLock wl = null;

private final Handler handler = new Handler() {
    public void handleMessage(Message msg) {
        String pnMsg = msg.obj.toString();

        final Toast toast = Toast.makeText(getApplicationContext(), pnMsg, Toast.LENGTH_SHORT);
        toast.show();

        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                toast.cancel();
            }
        }, 200);

    }
};

private void notifyUser(Object message) {

    Message msg = handler.obtainMessage();

    try {
        final String obj = (String) message;
        msg.obj = obj;
        handler.sendMessage(msg);
        Log.i("Received msg : ", obj.toString());

    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void onCreate() {
    super.onCreate();
    Toast.makeText(this, "PubnubService created...", Toast.LENGTH_LONG).show();
    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SubscribeAtBoot");
    if (wl != null) {
        wl.acquire();
        Log.i("PUBNUB", "Partial Wake Lock : " + wl.isHeld());
        Toast.makeText(this, "Partial Wake Lock : " + wl.isHeld(), Toast.LENGTH_LONG).show();
    }

    Log.i("PUBNUB", "PubnubService created...");
    try {
        pubnub.subscribe(new String[] {channel}, new Callback() {
            public void connectCallback(String channel) {
                notifyUser("CONNECT on channel:" + channel);
            }
            public void disconnectCallback(String channel) {
                notifyUser("DISCONNECT on channel:" + channel);
            }
            public void reconnectCallback(String channel) {
                notifyUser("RECONNECT on channel:" + channel);
            }
            @Override
            public void successCallback(String channel, Object message) {
                notifyUser(channel + " " + message.toString());
            }
            @Override
            public void errorCallback(String channel, Object message) {
                notifyUser(channel + " " + message.toString());
            }
        });
    } catch (PubnubException e) {

    }
}

@Override
public void onDestroy() {
    super.onDestroy();
    if (wl != null) {
        wl.release();
        Log.i("PUBNUB", "Partial Wake Lock : " + wl.isHeld());
        Toast.makeText(this, "Partial Wake Lock : " + wl.isHeld(), Toast.LENGTH_LONG).show();
        wl = null;
    }
    Toast.makeText(this, "PubnubService destroyed...", Toast.LENGTH_LONG).show();
}

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}

This service above is copied from this example. I call to start this service from my MainActivity. I call it like this from my onCreate method:

Intent serviceIntent = new Intent(this, PubNubService.class);
    startService(serviceIntent);

The one thing that Android Studio yells at me for is that the Handler class should be static or leaks would occur. When I run my app, the error that occurs is: [Error: 128-0] : Unable to get Response Code. Please contact support with error details. Unable to resolve host "pubsub-1.pubnub.com": No address associated with hostname. And on the next line [Error: 100-1] : Timeout Occurred.

My Android Manifest has this added:

<service android:name=".PubNubService"/>
Blaasd
  • 315
  • 3
  • 16
  • Does [this](https://github.com/pubnub/java/tree/master/android/examples/PubnubExample/src/com/pubnub/examples/pubnubExample10) help at all? – stkent Jan 26 '16 at 04:26
  • I mean like in order for PubNub to be subscribed to in the background as a service. I am looking for the absolute most basic and useless code so I can see how to properly structure the service so it will work, then I can add my own code to the base – Blaasd Jan 26 '16 at 05:14

1 Answers1

0

PubNub Minimal Android Sample Code to Publish & Subscribe

The simplest sort of example would be to just add all the code in a single Activity. All of the following code and be seen in PubNub Android SDK docs page.

import com.pubnub.api.*;
import org.json.*;


Pubnub pubnub = new Pubnub("your_pub_key", "your_sub_key");

pubnub.subscribe("channel1", new Callback() {
      @Override
      public void connectCallback(String channel, Object message) {
          System.out.println("SUBSCRIBE : CONNECT on channel:" + channel
                     + " : " + message.getClass() + " : "
                     + message.toString());
      }

      @Override
      public void disconnectCallback(String channel, Object message) {
          System.out.println("SUBSCRIBE : DISCONNECT on channel:" + channel
                     + " : " + message.getClass() + " : "
                     + message.toString());
      }

      public void reconnectCallback(String channel, Object message) {
          System.out.println("SUBSCRIBE : RECONNECT on channel:" + channel
                     + " : " + message.getClass() + " : "
                     + message.toString());
      }

      @Override
      public void successCallback(String channel, Object message) {
          System.out.println("SUBSCRIBE : " + channel + " : "
                     + message.getClass() + " : " + message.toString());
          // this is the messages received from publish
          // add these messages to a list UI component
      }

      @Override
      public void errorCallback(String channel, PubnubError error) {
          System.out.println("SUBSCRIBE : ERROR on channel " + channel
                     + " : " + error.toString());
      }
    }
  );

Callback callback = new Callback() { public void successCallback(String channel, Object response) { System.out.println(response.toString()); } public void errorCallback(String channel, PubnubError error) { System.out.println(error.toString()); } }; pubnub.publish("my_channel", "Hello from the PubNub Java SDK!" , callback);

You might have to make a few changes. For one, you should create a click method with the publish inside it that is bound to a button on your interface. And as noted in the successCallback for the subscribe method, you need to display the messages in a UI component on your Activity.

That should do it for you.

Subscribe at Boot

But there isn't really anything simpler than our Subscribe at Boot sample app that uses a Service to forward messages as Intents to an Activity.

Prevent Service Start on Device Boot

The fact that the Subscribe at Boot example starts up when the device is booted (powered on) is a matter of configuration. You can change the manifest so that it is only started when the app is started. See the SO thread Trying to start a service on boot on Android and undo the parts that make it start at boot.

This is full of helpful information on Android Services

More details on this in this SO thread "Is leaving a pubnub subscription open in a service optimal"

Community
  • 1
  • 1
Craig Conover
  • 4,710
  • 34
  • 59
  • I am looking for an example that is exactly like the Subscribe at Boot example, except that I do not want to subscribe at boot. I want to subscribe (start the service) from within an activity after a user has pushed a button. Is there an easy way to modify the Subscribe at Boot code so that it doesn't subscribe at boot but on choice? ** Just to clarify -- I already know how to subscribe and use PubNub while the app is running. I am looking for a way to subscribe to PubNub in a _service_ (aka in the background). – Blaasd Jan 27 '16 at 00:09
  • See the "Prevent Service Start on Device Boot" section I ended to the end of my answer. Let me know if that helps. – Craig Conover Jan 27 '16 at 01:46
  • 1
    Unable to get Response Code - this is a network connection error of some sort. And just a heads up, with Android 5, the background service is something you might not be able to do anymore and GCM may be your only choice. I will have an Android engineer review this for further insights for you. – Craig Conover Jan 27 '16 at 05:47
  • Okay thanks, for the network connection error, is there anything that I should look out for that might have caused it? Things I might have missed? – Blaasd Jan 27 '16 at 05:59
  • Also, am I to understand that there isn't a way to keep PubNub running in the background service on newer devices? – Blaasd Jan 28 '16 at 05:44
  • It's not PubNub issue but rather Android Services in general and keeping a socket open in Service in background. See this SO thread that is very similar to this one: http://stackoverflow.com/questions/35051528/is-leaving-a-pubnub-subscription-open-in-a-service-optimal – Craig Conover Feb 01 '16 at 05:43