0

I am trying to develop an android app to measure QoS of networks. The app sends UDP packets to a UDP server running on my system. Since this is a long running process, I have implemented the UDP connection in a class which extends IntentService.The reason behind using IntentService is that I need to pass some parameters to the Service. I have a BroadcastReceiver in my activity which listens for messages from the IntentService and prints it. My problem is that although the IntentService is running smoothly, but the activity is not receiving the messages from it. I am new to android development, so please excuse my lack of understanding and any guidance/suggestions will be deeply appreciated. I am posting some parts of my code below. The Logcat does not show any errors. I have seen intent.setAction() method being used in some examples, but I am not very clear about how to use it in my case.

The BroadcastReceiver (defined within my Activity class)

public class UdpResponseReceiver extends BroadcastReceiver {
 public static final String ACTION_RESP = "com.example.udpmessageclient.intent.action.MESSAGE_PROCESSED";
    @Override
    public void onReceive(Context context, Intent intent) {

        System.out.println(UdpService.PARAM_OUT_MSG);

    }

I have registered the receiver:

IntentFilter filter = new IntentFilter(UdpResponseReceiver.ACTION_RESP);
filter.addCategory(Intent.CATEGORY_DEFAULT);
receiver = new UdpResponseReceiver();
registerReceiver(receiver, filter);

IntentService class:

public class UdpService extends IntentService {

//..variable declarations

public UdpService() {
    // TODO Auto-generated constructor stub
    super("UdpService");
}

@Override
protected void onHandleIntent(Intent intent) {
    // TODO Auto-generated method stub
    host = intent.getStringExtra("host");
    port = intent.getIntExtra("port", 4000);
    pType= intent.getIntExtra("pType", 0);
    delay = intent.getIntExtra("delay", 0);
    msg= intent.getStringExtra("msg");
    broadcastIntent = new Intent();
    broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
    broadcastIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 

    try {
        addr = InetAddress.getByName(host);
        // addr=InetAddress.getLocalHost();
        socket = new DatagramSocket();
        // socket.connect(addr,port);

        System.out.println("\nSocket Connected");
    } catch (Exception e) {
        System.out.println("\nConnection failed");
        return;
    }

    send=true;
    switch (pType) {
    case 0:
        while (send) {
            sendPacket(msg);
        }
    case 1:
        while (send) {
            try {
                Thread.currentThread().sleep(delay);
            } catch (Exception e) {
            }
            sendPacket(msg);
        }
    case 2:
        while (send) {
            int u = want(30);
            String data1 = "";
            while ((u--) > 0)
                data1 = data1 + msg;
            sendPacket(data1);
        }
    case 3:
        while (send) {
            int u = want(30);
            System.out.println(u);
            String data1 = "";
            while ((u--) > 0)
                data1 = data1 + msg;
            System.out.println("data length :" + data1.length());
            try {
                Thread.currentThread().sleep(delay);
            } catch (Exception e) {
            }
            sendPacket(data1);
        }

    }
}
public void onDestroy(){
    super.onDestroy();
    send=false;
    socket.close();
    socket=null;

}
void sendPacket(String text) {

    try {
        System.out.println("\nClient:: Sending packet: " + " to " + addr
                + port);
        byte[] data = text.getBytes();
        spacket = new DatagramPacket(data, data.length, addr, port);
        socket.send(spacket);
        String resultTxt="Sent Packet at:"+DateFormat.format("MM/dd/yy h:mmaa", System.currentTimeMillis());

// this is where I am trying to send message back to the activity

    broadcastIntent.putExtra(PARAM_OUT_MSG, resultTxt);
        sendBroadcast(broadcastIntent);
    } catch (Exception e) {
        System.out.println("Error:" + e.getMessage());
        e.printStackTrace();
        return;
    }
}

}

logcat error messages when the service is stopped:

01-14 15:53:41.446: W/System.err(1176): java.lang.NullPointerException
01-14 15:53:41.456: W/System.err(1176):     at com.example.udpmessageclient.UdpService.sendPacket(UdpService.java:123)
01-14 15:53:41.466: W/System.err(1176):     at com.example.udpmessageclient.UdpService.onHandleIntent(UdpService.java:74)
01-14 15:53:41.466: W/System.err(1176):     at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
01-14 15:53:41.466: W/System.err(1176):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-14 15:53:41.466: W/System.err(1176):     at android.os.Looper.loop(Looper.java:137)
01-14 15:53:41.476: W/System.err(1176):     at android.os.HandlerThread.run(HandlerThread.java:60)
Poonam Anthony
  • 1,848
  • 3
  • 17
  • 27

1 Answers1

2

Change the code of UdpService as ...

broadcastIntent = new Intent(UdpResponseReceiver.ACTION_RESP); // You forgot to add your custom intent filter
broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
//broadcastIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); // I don't think you really need it. So you can remove this flag. 

UPDATE

public static final String ACTION_RESP = "com.example.udpmessageclient.intent.action.MESSAGE_PROCESSED";

private final BroadcastReceiver UdpResponseReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            //TODO handle results

        }
    }; 

And register it as

registerReceiver(UdpResponseReceiver, new IntentFilter(ACTION_RESP))
Pankaj Kumar
  • 81,967
  • 29
  • 167
  • 186
  • Thanks Pankaj. I added that line of code.But the problem still persists. The print statement within the **onReceive()** method of the BroadcastReceiver is not getting executed. – Poonam Anthony Jan 14 '13 at 09:44
  • Can you check that `sendBroadcast(broadcastIntent)` is getting called or not using logs? And one more test attempt is to check it without using `broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT)`, and call `registerReceiver(UdpResponseReceiver, new IntentFilter(UdpResponseReceiver.ACTION_RESP))`. Where declairation of Receiver I added in my answer. – Pankaj Kumar Jan 14 '13 at 09:56
  • The problem got solved by replacing `System.out.println(UdpService.PARAM_OUT_MSG);` with `System.out.println(intent.getStringExtra(UdpService.PARAM_OUT_MSG));` I had overlooked this mistake. Thanks for your time and help Pankaj – Poonam Anthony Jan 14 '13 at 10:09
  • I have one more query regarding this same code.shall i post it here or start a new thread? – Poonam Anthony Jan 14 '13 at 10:13
  • when I stop the service it causes a NullPointerExecption. I am stopping the service from the activity by calling `stopService(udpServiceIntent);` What I understood from the logcat is that the program still tries to execute `socket.send(spacket);` even after the service is stopped and the socket is closed. How can this be avoided? I am posting the logcat messages in the main question – Poonam Anthony Jan 14 '13 at 10:25
  • Sort answer don't call stopService method. Make `send` variable as public static in UdpService. And when you want to stop the service (logically you want to exit while loop, right?) simply set that `send` variable to `false` from Activity. This will work. And yes one more thing I got a link which can explain that why I am saying to not call stopService for an IntentService. link is here http://stackoverflow.com/questions/10362981/stop-intentservice-from-activity – Pankaj Kumar Jan 14 '13 at 11:22
  • Sorry I'm not very clear as to why you suggest not calling stopService(). could you please elaborate? – Poonam Anthony Jan 14 '13 at 11:35
  • Sometime IntentServices wait until task in onhandleintent() is not finished although you had call stopService(). That why I am saying to not call and use alternate solution. BUT REMEMBER that my comment is only for this requirement (as in your question). – Pankaj Kumar Jan 14 '13 at 11:46
  • Thanks a lot for your suggestions. But I added an additional `if` condition to check whether `socket` is null or not before executing `socket.send()`, and it works for me. – Poonam Anthony Jan 15 '13 at 08:12