1
votes

I've been trying to make a simple Phonegap app that receives Parse Push notifications on Android. I've read a number of tutorials and read through related issues here and elsewhere but i can't seem to get it to work without crashing.

I have the latest of Java JDK, Cordova + Node JS + plugman, Android API 19 (seems to be required by cordova), Apache ant, etc...

Bottom line: I can start the app. I can receive the notification just fine. But when I tap the notification to go back to the app it always crashes.

Question? Can anyone explain why this is happening? Or even better if you have a sample project that works? Any help would be greatly appreciated.

References:

https://parse.com/tutorials/android-push-notifications

http://www.raymondcamden.com/2012/10/10/PhoneGap-Parsecom-and-Push-Notifications -- a bit out of date

How do I get Parse.com Push Notifications working in a Cordova/Phonegap Android app?

apache cordova app crashes after receiving parse.com push notification

Sources:

AndroidManifest.xml

<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="1" android:versionName="0.0.1" package="com.company.challenger" xmlns:android="http://schemas.android.com/apk/res/android">
    <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <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:name="com.company.challenger.permission.C2D_MESSAGE" android:protectionLevel="signature" />
    <uses-permission android:name="com.company.challenger.permission.C2D_MESSAGE" />
    <application android:hardwareAccelerated="true" android:icon="@drawable/icon" android:label="@string/app_name" android:name="com.company.challenger.ChallengerApplication">
        <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/app_name" android:launchMode="singleTop" android:name="ChallengerApplication" android:theme="@android:style/Theme.Black.NoTitleBar" android:windowSoftInputMode="adjustResize">
            <intent-filter android:label="@string/launcher_name">
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <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.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="com.company.challenger" />
            </intent-filter>
        </receiver>
        <receiver android:exported="false" android:name="com.parse.ParsePushBroadcastReceiver">
            <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>
    </application>
    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="19" />
</manifest>

CordovaApp.java

package com.company.challenger;

import com.parse.ParseAnalytics;
import android.os.Bundle;
import org.apache.cordova.*;

public class CordovaApp extends CordovaActivity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        super.init();
        // Set by <content src="index.html" /> in config.xml
        loadUrl(launchUrl);
        ParseAnalytics.trackAppOpened(getIntent());
    }
}

ChallengerApplication.java

package com.company.challenger;

import android.app.Application;
import android.content.Context;

import com.parse.Parse;
import com.parse.ParseInstallation;
import com.parse.PushService;

import com.company.challenger.CordovaApp;

public class ChallengerApplication extends Application 
{
    private static ChallengerApplication instance = new ChallengerApplication();

    public ChallengerApplication() {
        instance = this;
    }

    public static Context getContext() {
        return instance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        // register device for parse
        Parse.initialize(this, "app key", "client key");
        PushService.setDefaultPushCallback(this, CordovaApp.class);
        ParseInstallation.getCurrentInstallation().saveInBackground();
    }
}
1
If you are using phonegap then why Android api of parse and why not JS api ? - MohK
as far as i understand you still need to register the android installation with parse to receive push notifications. only the push installation is with Andoird. the rest is JS - mxs
any update on this? Having similar issues. - James Gilchrist
Please Check my Answer here. stackoverflow.com/questions/24685462/… - Im Batman
I ended up hacking together something that worked by mixing and matching code from various sources. Start with the parse push guide and then adding one of the Cordova parse push plugins is a good start. Some of them are really old or slightly broken so some tweaking is required. - mxs

1 Answers

0
votes

Proper answer this time...

I basically started from scratch following the latest parse tutorial and making sure the initialize parse in the MainApplication and not in your javascript.

This is the gist:

  1. Create a MainApplication.java with a skeleton like this:

    package com.{your_company}.{your_app};
    import android.app.Application;
    import android.content.Context;

    import com.parse.Parse;
    import com.parse.ParsePush;
    import com.parse.SaveCallback;
    import com.parse.ParseException;

    import com.{your_company}.{your_app}.MainActivity;

    public class MainApplication extends Application 
    {
            @Override
            public void onCreate() {
                super.onCreate();
                // parse initialization goes here
            }
    }

  1. Add the following attribute to your application tag in AndroidManifest.xml

    <application ... android:name="com.{your_company}.{your_app}.MainApplication">

  1. Follow this tutorial from Parse.com which is fairly decent https://parse.com/tutorials/android-push-notifications .

  2. The final onCreate in MainApplication.java should look something like this:


    @Override
    public void onCreate() {
       super.onCreate();
       Parse.enableLocalDatastore(app);
       Parse.initialize(app, "{app_key}", "{client_key}");

       ParsePush.subscribeInBackground("", new SaveCallback() {
          @Override
          public void done(ParseException e) {
             if (e == null) {
                Log.d("com.parse.push", "successfully subscribed to the broadcast channel.");
             } else {
                Log.e("com.parse.push", "failed to subscribe for push", e);
             }
          }
       });
    }

From this experience I found the following insights:

  • Not recommended to use any parse push plugins floating around because there are all out of date using deprecated calls or simply did not work out of the box.
  • The Parse initialize must occur in the MainApplication and cannot occur in the javascript. (I don't have the reference for this one, I came across it somewhere down the line when frantically researching).
  • Always use the latest Parse SDK and use ParsePush (the new service) and not PushService which is depricated.

Hopefully this helps.