Skip to content

Setting Up Push For Android

Chidiebere Okwudire edited this page Jan 24, 2017 · 20 revisions

This page describes how to set up push notifications for Android in a CodenameOne app using push services provided by Parse.

Note: This solution is not compatible with push notifications provided by CodenameOne. Make sure that the includePush build hint is set to false (ios.includePush=false) to be double sure!

Setting up Push for Android

Setting up Push notifications via Parse for Android is quite straightforward. Parse4CN1 already includes the Parse Android native SDK so all that needs to be done is to configure your cn1 app so that it can use this SDK. This is achieved using cn1 build hints as explained shortly.

Obtain a GCM sender ID

Create a GCM sender ID via the Google Developer Console as explained here.

Note: You will need to link the Google project you created at https://console.developers.google.com to a (new) Firebase project at https://console.firebase.google.com. After that, you’ll be able to see the desired sender ID in the project credentials in Firebase.

  • If using a self-hosted Parse Server, follow the configuration steps here.
  • If using a Parse Server hosting service like back4app or sashido.io, follow the corresponding documentation on how to upload your GCM sender ID to their backend.

Initialize the Parse SDK

The Parse SDK must be initialized. This must occur in an Android Application context (not in an activity context).

Note: If initialization is done in an activity instead of in the Application class, Push notifications will only be received when the application is running as explained in the answers in (1), (2).

Create an Application class

There are two options for getting up and running with an application class.

Case 1: No existing application class

By default, CN1 Android apps don't have an application class so this would be the best option unless you've already explicitly created an application class for other purposes (in which case you'd need to extend it as explained in 'Case 2' below). Basically, you'd start with the template CN1AndroidApplication class present in the parse4cn1 test app project and customize it as needed.

  • In your cn1 app, go to the /native/android directory
  • Create a sub-directory path for /com/parse4cn1/nativeinterface if one does not exist
  • Copy file CN1AndroidApplication.java from the parse4cn1 test app project into that directory
  • Open the file and use your own Parse app credentials (Server URL, ApplicationId and ClientKey) in the Parse.initialize() method call in the onCreate() method (search for 'TODO' to be sure you've updated everything)
  • Feel free to customize the class to meet your needs

Case 2: Extending an existing application class

It could be that you already have an application class for other purposes. In that case, all you need to do is to merge the contents of file CN1AndroidApplication.java from the parse4cn1 test app project into your existing application class. Of course, you can skip parts that are not relevant to you, e.g., because you have your own implementation (such as tracking of application state).

Specify your Application class in the AndroidManifest.xml

Android needs to know about your custom application class. This can be realized using the android.xapplication_attr cn1 build hint with value android:name="your.app.package.name.ApplicationClassName" where ApplicationClassName is the name of the Application class you created in the previous step.

  • If you used option 1 above, it will be android:name="com.parse4cn1.nativeinterface.CN1AndroidApplication".
  • If you used option 2 above, your.app.package.name is the same as the package declaration at the top of your Android application java file.

Set up push notifications

For push notifications to work, a push service, broadcast receivers and certain permissions are needed. These are already provided by the Parse SDK and/or parse4cn1 and only need to be specified in your cn1 app's AndroidManifest.xml via cn1 build hints

Create a PushBroadcastReceiver (optional but strongly recommended)

The Parse SDK includes a ParsePushBroadcastReceiver whose source code is avaiable on github here. If that meets your needs then you should skip this step.

However, if you want interaction between the native push and your app, you'd definitely need more. The parse4cn1 test app project includes an implementation that is illustrates how this can be done. Check it out in CN1ParsePushBroadcastReceiver.java. This implementation realizes the reference implementation described here. The choice is yours on what BroadcastReceiver to use and ultimately depends on your needs.

If you choose to use 'CN1ParsePushBroadcastReceiver', here's how you can quickly integrate it into your app.

  • In your cn1 app, go to the /native/android directory
  • Create a sub-directory path for /com/parse if one does not exist
  • Copy CN1ParsePushBroadcastReceiver.java from the parse4cn1 test app project into that directory
  • Feel free to customize the class to meet your needs

Set up the Push service

Register the push service and broadcast receivers by adding the following to the android.xapplication build hint

<!--
 IMPORTANT: Replace "<your_sender_id>" with your GCM/FCM sender ID.
-->
<meta-data android:name="com.parse.push.gcm_sender_id" android:value="id:<your_sender_id>" />;

<service android:name="com.parse.PushService" />

<receiver android:name="com.parse.ParseBroadcastReceiver">
  <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED" />
    <action android:name="android.intent.action.USER_PRESENT" />
  </intent-filter>
</receiver>

<!--
     IMPORTANT: Note that if you created a custom ParsePushBroadcastReceiver 
     as described above, make sure you change the value of the android:name atrribute below to 
     "your.app.package.name.PushBroadcastReceiverName".
     The following assumes that you use the customized "CN1ParsePushBroadcastReceiver"
     If you used the default ParsePushBroadcastReceiver from the SDK, it would be "com.parse.ParsePushBroadcastReceiver"
-->
<receiver android:name="com.parse.CN1ParsePushBroadcastReceiver"
android:exported="false">
  <intent-filter>
    <action android:name="com.parse.push.intent.RECEIVE" />
    <action android:name="com.parse.push.intent.DELETE" />
    <action android:name="com.parse.push.intent.OPEN" />
  </intent-filter>
</receiver>

<receiver android:name="com.parse.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
  <intent-filter>
    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
    <!--
     IMPORTANT: Change "<your.app.package.name>" to match your app's package name.
	-->
    <category android:name="<your.app.package.name>" />
  </intent-filter>
</receiver>

Here's a comment-free, line break-free version of the code above that you can directly add to the build hint (of course, after changing the necessary parameters as mentioned above, if applicable):

 <meta-data android:name="com.parse.push.gcm_sender_id" android:value="id:<your_sender_id>" /> <service android:name="com.parse.PushService" /> <receiver android:name="com.parse.ParseBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.USER_PRESENT" /> </intent-filter> </receiver> <receiver android:name="com.parse.CN1ParsePushBroadcastReceiver" android:exported="false"> <intent-filter> <action android:name="com.parse.push.intent.RECEIVE" /> <action android:name="com.parse.push.intent.DELETE" /> <action android:name="com.parse.push.intent.OPEN" /> </intent-filter> </receiver> <receiver android:name="com.parse.GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND"> <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> <category android:name="<your.app.package.name>" /> </intent-filter> </receiver>

Set the required permissions

Add the following permissions required for Parse push to the AndroidManifest.xml via the android.xpermissions build hint

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!--
  IMPORTANT: Change "<your.app.package.name>" in the lines below
  to match your app's package name.
-->
<permission android:protectionLevel="signature"
    android:name="<your.app.package.name>.permission.C2D_MESSAGE" />
<uses-permission android:name="<your.app.package.name>.permission.C2D_MESSAGE" />

Here's a comment-free, line break-free version of the code above that you can directly add to the build hint (of course, after changing "your.app.package.name" as mentioned above):

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <permission android:protectionLevel="signature"     android:name="<your.app.package.name>.permission.C2D_MESSAGE" /> <uses-permission android:name="<your.app.package.name.permission>.C2D_MESSAGE" />

Implement app logic for processing incoming push messages

If all you need is to be able to receive push messages and for your app to be opened when they are clicked, you can safely continue to the next step. However, if you have more advanced needs like processing incoming push data, switching forms based on contents of push messages, handling silent push messages, etc., you should definitely take a moment to review this section of the reference implementation that describes how you can realize such customizations.

Compile and run

You're done. Compile your app, deploy to a (real) device, send a push notification via the Parse dashboard push console or using parse4cn1 and you should receive it on your device. If not:

  • Review the steps above for possible mistakes
  • Compare your implementation with that in the parse4cn1 test app (an apk is already available for direct installation and testing)
  • Debug via adb to see the device logging which might contain useful information
  • Check out the troubleshooting and links sections below for more tips

Troubleshooting

1. Unable to receive push messages

If you are unable to receive push messages, there are a few troubleshooting steps you can take:

  1. Is your installation being created? Check this on the Parse dashboard.
  2. If the installation is created:
  • Confirm that the installation object has non-empty deviceToken and installationId fields and that pushType=gcm and deviceType=android. Moreover, fields appIdentifier (=packageName) and appName should be filled with expected values from your CN1 app's settings.
  • If any of the above fields is missing, it is most likely the case that you have a typo in one of your build hints. Double- and triple-check your build hints!
  1. If these don't help, try googling or asking on the Parse discussion forum or if you think it's a parse4cn1 issue, create a ticket in Github.

Useful links