I have a WakefulBroadcastReceiver in my Android application, which successfully receives incoming SMS to the device. Following this, what I am attempting to do, is to submit a request to my web server, using the Google Volley library. The issue, is that Volley makes this web request asynchronously. As a result, the "onReceive" method code in the BroadcastReceiver is completed before the asynchronous web request is completed. I understand that this is an issue when using the BroadcastReceiver with asynchronous requests, but I'm making that request through a service, (instead of directly in the BroadcastReceiver), so I don't understand why this is happening.
I receive the below NULLPOINTEREXCEPTION, which I'm assuming is because the context of the BroadcastReceiver has already been destroyed before the request is completed:
11-04 19:13:43.465 32385-32441/com.niiche.pinch E/Volley﹕ [5542] NetworkDispatcher.run: Unhandled exception java.lang.NullPointerException
java.lang.NullPointerException
at libcore.net.UriCodec.encode(UriCodec.java:132)
at java.net.URLEncoder.encode(URLEncoder.java:57)
at com.android.volley.Request.encodeParameters(Request.java:456)
at com.android.volley.Request.getBody(Request.java:442)
at com.android.volley.toolbox.HurlStack.addBodyIfExists(HurlStack.java:236)
at com.android.volley.toolbox.HurlStack.setConnectionParametersForRequest(HurlStack.java:210)
at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:106)
at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:96)
at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:110)
Below is the code for the WakefulBroadcastReceiver (SmsReceiver):
public void onReceive(Context context, Intent intent) {
//retrieve the SMS PDUs, from the intent extras
Bundle pdusBundle = intent.getExtras();
Object[] pdus = (Object[])pdusBundle.get("pdus");
//create sms message object from the PDU
SmsMessage message = SmsMessage.createFromPdu((byte[])pdus[0]);
Intent service = new Intent(context, SmsIntentService.class);
service.putExtra(SmsIntentService.EXTRA_SMS_MESSAGE, message.getMessageBody());
//start the service, keeping the device awake while it is launching
startWakefulService(context, service);
setResultCode(Activity.RESULT_OK);
}//End method
Below is the code for the IntentService (SmsIntentService):
protected void onHandleIntent(Intent intent) {
if (intent != null) {
Bundle extras = intent.getExtras();
if(!extras.isEmpty()){ // has the effect of unparcelling the bundle
String smsMessage = extras.getString(EXTRA_SMS_MESSAGE);
submitVolleyServerRequestAsync(smsMessage);
}//End if
}//End if
// Release the wake lock provided by the WakefulBroadcastReceiver
SmsReceiver.completeWakefulIntent(intent);
}//End method
Any assistance that can be provided here is greatly appreciated. Thanks in advance!
Thanks for the pointers @Aun and @CommonsWare. My issue was actually with how I was creating the Volley request. Volley apparently does not handle input parameter values, (i.e. HTTP Get/Post Params), being passed as null. I had to check therefore whether each param was null, before adding it to the param map for the request:
Map<String, String> mapPostArgs = new HashMap<String, String>();
if(name != null) {
mapPostArgs.put("name", name);
}
GsonRequest<APIResponse<Integer>> request = new GsonRequest<APIResponse<Integer>>(
uri,
new TypeToken<APIResponse<Integer>>(){}.getType(),
getRequestHeaders(),
mapPostArgs,
listener,
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
handleError(error);
}//End method
});
Thanks alot for the guidance!