Android app crashing on receiving backendless push notification

Hi Guys, This is related to and maybe explains in part this topic. http://support.backendless.com/t/push-notification-api-to-all-devices-not-all-getting-delivered
Upon sending out a push notification I got a crash cluster. This is the information I got from the crashes:
java.lang.RuntimeException: at android.os.AsyncTask$3.done (AsyncTask.java:318) at java.util.concurrent.FutureTask.finishCompletion (FutureTask.java:354) at java.util.concurrent.FutureTask.setException (FutureTask.java:223) at java.util.concurrent.FutureTask.run (FutureTask.java:242) at android.os.AsyncTask$SerialExecutor$1.run (AsyncTask.java:243) at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1133) at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:607) at java.lang.Thread.run (Thread.java:762)Caused by: java.lang.NullPointerException: at com.backendless.AndroidBackendlessPrefs.restoreAuthKeysFromPreferences (AndroidBackendlessPrefs.java:103) at com.backendless.AndroidBackendlessPrefs.getAuthKeys (AndroidBackendlessPrefs.java:96) at com.backendless.AndroidBackendlessPrefs.getApplicationId (AndroidBackendlessPrefs.java:51) at com.backendless.Backendless.getApplicationId (Backendless.java:190) at com.backendless.Messaging.getRegistrations (Messaging.java:322) at com.backendless.Messaging.getDeviceRegistration (Messaging.java:317) at com.conceiveit.adventuregolf.golfapp1.MyPushService$MyAsyncTaskPushReceived.doInBackground (MyPushService.java:174) at com.conceiveit.adventuregolf.golfapp1.MyPushService$MyAsyncTaskPushReceived.doInBackground (MyPushService.java:143) at android.os.AsyncTask$2.call (AsyncTask.java:304) at java.util.concurrent.FutureTask.run (FutureTask.java:237)

This is the documented code inside myPushService MyAsyncTaskPushReceived. Can you see what I am doing wrong? What I am trying to achieve is a table of devices which have successfully received and read the push notification. Works perfectly on my test device, but when sending out to other users I suddenly got a lot of crashes. Any advice please on what I am doing wrong, how I fix it or handle the error to avoid crashs would be gratefully received!!
try {

//Register the Push notification on a backendless table.     //PushMessagesReceived is just a new row in table called PushMessagesReceived
PushMessagesReceived newReceived;
newReceived = new PushMessagesReceived();

String messageID;
messageID = params[0];


newReceived.setMessageID(messageID);

// This is where I think the problem is.
DeviceRegistration devReg = Backendless.Messaging.getDeviceRegistration();
newReceived.setDeviceID(devReg.getDeviceId());

//save
Backendless.Persistence.save(newReceived);

} catch (BackendlessException exception) {
System.out.println(exception.toString());
}

The code you’ve shared looks valid, but its not enough to understand what and where exactly goes wrong. Please zip up a minimal project to reproduce the problem (by minimal I mean not the whole project but the minimum code required to reproduce the behavior you’ve described) and send it to support@backendless.com. Otherwise investigation will be problematic.

Best Regards

Hi Anton, OK I’m just about to send you a zip file, regards Mike

Hi I see my status was updated to Need Answer - did you get my zip file with the project?

Yes, we’ve got your project. Can we create a new messaging channel for testing push notifications in your App?

Regards, Olga

Hi Mike,

The services in Android (e.g. your MyPushService class) act like they’re separate apps, meaning they don’t share any Context with your Application classes. So in your case, the error is here:

Caused by: java.lang.NullPointerException: at com.backendless.AndroidBackendlessPrefs.restoreAuthKeysFromPreferences (AndroidBackendlessPrefs.java:103)
....
at com.backendless.Messaging.getDeviceRegistration (Messaging.java:317) 
at com.conceiveit.adventuregolf.golfapp1.MyPushService$MyAsyncTaskPushReceived.doInBackground (MyPushService.java:174)

which is caused by Backendless classes not being initialized.

To resolve this, add Backendless.initApp() call at the start of the service’s lifecycle or directly before you call any Backendless API method, e.g. in the beginning of MyPushService.doInBackground() method from your sample.

Hi Olga, yes you can do that provided users of the app wouldn’t get the message! That would look very bad on my part. Perhaps test message could say ‘Christmas is coming, why not buy some Christmas vouchers from our website?’ just in case something goes wrong and anyone gets a message!

Hi Sergey - OK got ya, yes that makes sense, thanks. However when testing on my device I wasn’t getting any null exception and the message was displayed ok even if wasn’t using the app? Is this perhaps because the call to Backendless.initApp() would have still been alive somehow?

I suppose, the following happens: when you test it on your device, you have both your app and the background service launched - and, well, probably they do share something, like Backendless initialized classes.
But it is possible that the service is launched without the main app being launched - like, for example, when the user haven’t opened your app for a while, but the notifications still come, so the background service is launched to process it. In this case, since you have no Backendless.initApp() call in a service, it crashes.
In general, this means you should write the App and the Background Service as if they were totally separate programs, even though in some cases they might share some context.

Yes agreed, I will put that call in and update the app and try some new messages.

Hi Sergey, This is possibly more related to http://support.backendless.com/t/push-notification-api-to-all-devices-not-all-getting-delivered but it was because of this bug and your solution that I discovered this…

I thought all my notifications to my test devices were getting delivered, but in fact they are not. If I leave the test device for a certain amount of time (not sure what - I guess until the app is properly put in the background) then notifications do not seem to be received…

I have gone back and followed all the documentation again for the Android setup. What I am unsure of though is should my class (MyPushService) which extends BackendlessPushService be running as a service? I think it should be but it is not and perhaps that is why notifications are not being received? I can’t find anywhere in the backendless docs which says to call startService on the PushService class so wondered if you could clarify that for me?

What do you think - if I add 2 override methods - onBind, and onStartCommand to the MyPushService I can add it as a service and then call startService(newIntent(getBaseContext(), MyPushService.class).

Am I on the right track?

Regards

Mike

OK, this didn’t seem to help in fact it made things worse, but I am still confused by this. I would be grateful if you could have another look at my project and see if I have done anything wrong which may prevent messages not being delivered if the app has not been used for a while?

Have you specified the receiver in AndroidManifest.xml according to this doc section?

Yes, I have. I have custom handling of the push notifications so this is what manifest looks like. (replaced my real package with com.yPackage)

<!-- push notification -->

<intent-filter>


<category android:name=“com.myPackage” />
</intent-filter>
</receiver>
<service android:name=".MyPushService" />

Looking at those docs, before handling custom notifications,

is in the manifest, but if you handle notifications with customisation then it is not
in the docs. Should I take this line out of the manifest?

I suppose the REGISTRATION action should still be there, we’re going to fix this inconsistency in the docs. Your configuration looks fine, and considering that you receive the messages while the app is active - it works fine, too.
As to your question about whether your PushService extending BackendlessPushService should be running as a service - yes, it should, and this part is essential for receiving and handling the notifications while your app is in background. So, at this point, I’d suggest you to make sure that the service remains running when the app goes to background after a certain amount of time - probably add some logs or try to find more information on the web on how to detect whether the service is functional.

OK thanks, I don’t think it running as a service then. Let me investigate and come back to you if I can’t figure that one out.