1

I'm using Parse.com service to send a push notification and have a broadcast receiver to receive the message. I want to call a method in my activity from broadcast receiver to show a Toast message(Actually I wanted to update listview content but for now I just use Toast to check if the method was called successfully) without calling the activity.

First I follow this instruction :

but it produce errors :

12-20 20:53:33.892: E/AndroidRuntime(14245): FATAL EXCEPTION: main
12-20 20:53:33.892: E/AndroidRuntime(14245): java.lang.RuntimeException: Unable to start receiver event.planner.services.CustomReceiver: java.lang.NullPointerException
12-20 20:53:33.892: E/AndroidRuntime(14245):    at android.app.ActivityThread.handleReceiver(ActivityThread.java:2236)
12-20 20:53:33.892: E/AndroidRuntime(14245):    at android.app.ActivityThread.access$1500(ActivityThread.java:130)
12-20 20:53:33.892: E/AndroidRuntime(14245):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1271)
12-20 20:53:33.892: E/AndroidRuntime(14245):    at android.os.Handler.dispatchMessage(Handler.java:99)
12-20 20:53:33.892: E/AndroidRuntime(14245):    at android.os.Looper.loop(Looper.java:137)
12-20 20:53:33.892: E/AndroidRuntime(14245):    at android.app.ActivityThread.main(ActivityThread.java:4745)
12-20 20:53:33.892: E/AndroidRuntime(14245):    at java.lang.reflect.Method.invokeNative(Native Method)
12-20 20:53:33.892: E/AndroidRuntime(14245):    at java.lang.reflect.Method.invoke(Method.java:511)
12-20 20:53:33.892: E/AndroidRuntime(14245):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
12-20 20:53:33.892: E/AndroidRuntime(14245):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
12-20 20:53:33.892: E/AndroidRuntime(14245):    at dalvik.system.NativeStart.main(Native Method)
12-20 20:53:33.892: E/AndroidRuntime(14245): Caused by: java.lang.NullPointerException
12-20 20:53:33.892: E/AndroidRuntime(14245):    at event.planner.services.CustomReceiver.onReceive(CustomReceiver.java:60)
12-20 20:53:33.892: E/AndroidRuntime(14245):    at android.app.ActivityThread.handleReceiver(ActivityThread.java:2229)
12-20 20:53:33.892: E/AndroidRuntime(14245):    ... 10 more
12-20 20:53:35.883: I/Process(14245): Sending signal. PID: 14245 SIG: 9
12-20 20:53:41.322: E/Trace(15934): error opening trace file: No such file or directory (2)
12-20 20:53:41.615: E/com.parse.PushService(15934): The Parse push service cannot start because Parse.initialize has not yet been called. If you call Parse.initialize from an Activity's onCreate, that call should instead be in the Application.onCreate. Be sure your Application class is registered in your AndroidManifest.xml with the android:name property of your <application> tag.

and then I tried to use static method as described here, it produces the following error:

12-20 20:18:49.553: E/AndroidRuntime(11779): FATAL EXCEPTION: main
12-20 20:18:49.553: E/AndroidRuntime(11779): java.lang.RuntimeException: Error receiving broadcast Intent { act=com.example.UPDATE_STATUS flg=0x10 (has extras) } in event.planner.services.CustomReceiver@41036bd0
12-20 20:18:49.553: E/AndroidRuntime(11779):    at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:765)
12-20 20:18:49.553: E/AndroidRuntime(11779):    at android.os.Handler.handleCallback(Handler.java:615)
12-20 20:18:49.553: E/AndroidRuntime(11779):    at android.os.Handler.dispatchMessage(Handler.java:92)
12-20 20:18:49.553: E/AndroidRuntime(11779):    at android.os.Looper.loop(Looper.java:137)
12-20 20:18:49.553: E/AndroidRuntime(11779):    at android.app.ActivityThread.main(ActivityThread.java:4745)
12-20 20:18:49.553: E/AndroidRuntime(11779):    at java.lang.reflect.Method.invokeNative(Native Method)
12-20 20:18:49.553: E/AndroidRuntime(11779):    at java.lang.reflect.Method.invoke(Method.java:511)
12-20 20:18:49.553: E/AndroidRuntime(11779):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
12-20 20:18:49.553: E/AndroidRuntime(11779):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
12-20 20:18:49.553: E/AndroidRuntime(11779):    at dalvik.system.NativeStart.main(Native Method)
12-20 20:18:49.553: E/AndroidRuntime(11779): Caused by: java.lang.NullPointerException
12-20 20:18:49.553: E/AndroidRuntime(11779):    at android.widget.Toast.<init>(Toast.java:92)
12-20 20:18:49.553: E/AndroidRuntime(11779):    at android.widget.Toast.makeText(Toast.java:238)
12-20 20:18:49.553: E/AndroidRuntime(11779):    at event.planner.front.FrontLayout.UpdateList(FrontLayout.java:193)
12-20 20:18:49.553: E/AndroidRuntime(11779):    at event.planner.services.CustomReceiver.onReceive(CustomReceiver.java:60)
12-20 20:18:49.553: E/AndroidRuntime(11779):    at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:755)
12-20 20:18:49.553: E/AndroidRuntime(11779):    ... 9 more
12-20 20:18:52.613: I/Process(11779): Sending signal. PID: 11779 SIG: 9
12-20 20:18:58.762: E/Trace(12109): error opening trace file: No such file or directory (2)
12-20 20:18:59.603: E/com.parse.PushService(12109): The Parse push service cannot start because Parse.initialize has not yet been called. If you call Parse.initialize from an Activity's onCreate, that call should instead be in the Application.onCreate. Be sure your Application class is registered in your AndroidManifest.xml with the android:name property of your <application> tag.

How to do this properly? Thank you.

My code after combining both methods:

CustomReceiver.java

public class CustomReceiver extends BroadcastReceiver {
    private static final String TAG = "MyCustomReceiver";
    public static final String ACTION = "com.example.UPDATE_STATUS";

    FrontLayout main = null;
    public void setMainActivityHandler(FrontLayout main){
        this.main=main;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String title="";
        String alert="";
        try {
            JSONObject json = new JSONObject(intent.getExtras().getString("com.parse.Data"));

            Iterator<?> itr = json.keys();
            while (itr.hasNext()) {
                String key = (String) itr.next();
                if(key.equals("title"))
                    title = json.getString(key);
                if(key.equals("alert"))
                    alert = json.getString(key);
                else
                    continue;
            }
         } catch (JSONException e) {
            Log.w(TAG, "JSONException: " + e.getMessage());
         }

        SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss",Locale.US);
        Date date = new Date();

        NotificationModel nm = new NotificationModel();
        nm.setTitle(title);
        nm.setAlert(alert);
        nm.setDateTime(dateFormat.format(date));

        NotificationDS nds = new NotificationDS(context);
        nds.insertNotification(nm);

        main.UpdateList();
    }
}

AndroidManifest.xml

<application>
.....
<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="event.planner.services.CustomReceiver"
                android:exported="false">
            <intent-filter>
                <action android:name="com.example.UPDATE_STATUS" />
            </intent-filter>
            </receiver>
    </application>
    <application android:name="event.planner.services.MyApplication">
    </application>

FrontLayout.java

public class FrontLayout extends Activity 
{
   ....
   CustomReceiver receiver = null;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
   ......

   receiver = new CustomReceiver();
        receiver.setMainActivityHandler(this);
        IntentFilter callInterceptorIntentFilter = new IntentFilter("com.example.UPDATE_STATUS");
        registerReceiver(receiver, callInterceptorIntentFilter);

   }

   public static void UpdateList()
   {
       Toast.makeText(MyApplication.getAppContext(), "Success!", Toast.LENGTH_SHORT).show();
   }
}

MyApplication.java

package event.planner.services;

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

public class MyApplication extends Application{

    private static Context context;

    public void onCreate(){
        super.onCreate();
        MyApplication.context = getApplicationContext();
    }

    public static Context getAppContext() {
        return MyApplication.context;
    }
}
Community
  • 1
  • 1
Andika R
  • 79
  • 4
  • 15

1 Answers1

13

Follow these steps

Step 1:Declare a Interface class in that BroadcastReceiver

Step 2: Implement that interface in your Activity class...

sample code:

Inside CustomReceiver.class---------

public interface Listener {
    public void onUIChanges();
}

public void setListener(Listener listener) {
    CustomReceiver .listener = listener;
}

@Override
public void onReceive(Context context, Intent intent) 
{
-------
 ------

if(listener!=null)

   {
 listener.onUIChanges();
 }
 }

Inside FrontLayout.class

CustomReceiver.setListener(this);  // otherwise null pointer occurs

And finally implement that listener...

KP_
  • 1,854
  • 25
  • 43
  • Declaring interface class in BroadcastReceiver produce an error : "The member interface can only be defined inside a top-level class or interface". Then I tried to make a new Interface class, implement a method in my activity class, and call that method by `MyInterface mi = new FrontLayout(); mi.MyMethod();` but still produce a null pointer. – Andika R Dec 21 '13 at 23:53
  • check edited answer..If it helps ,accepts this answer..Thanks. – KP_ Dec 22 '13 at 02:46