3

I am trying to show an alert message in onMessageReceived of the MyFirebaseMessagingService class and I get an error:

    java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
                                                                                    at android.os.Handler.<init>(Handler.java:200)
                                                                                    at android.os.Handler.<init>(Handler.java:114)
                                                                                    at android.app.Activity.<init>(Activity.java:846)
                                                                                    at android.support.v4.app.SupportActivity.<init>(SupportActivity.java:38)
                                                                                    at android.support.v4.app.BaseFragmentActivityApi14.<init>(BaseFragmentActivityApi14.java:28)
                                                                                    at android.support.v4.app.BaseFragmentActivityApi16.<init>(BaseFragmentActivityApi16.java:34)
                                                                                    at android.support.v4.app.FragmentActivity.<init>(FragmentActivity.java:67)
                                                                                    at android.support.v7.app.AppCompatActivity.<init>(AppCompatActivity.java:61)
                                                                                    at com.dopay.onboarding.activity.BaseActivity.<init>(BaseActivity.java:51)
                                                                                    at com.dopay.onboarding.FMS.MyFirebaseMessagingService.onMessageReceived(MyFirebaseMessagingService.java:75)
                                                                                    at com.google.firebase.messaging.FirebaseMessagingService.handleIntent(Unknown Source)
                                                                                    at com.google.firebase.iid.zzc.run(Unknown Source)
                                                                                    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)
02

What I have tried.

@Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        if (remoteMessage.getData().size() > 0) {
 BaseActivity baseActivity = new BaseActivity();
                baseActivity.showDialog();
}

}

BaseActivity

  public void showDialog(){
        this.runOnUiThread(new Runnable() {
            public void run() {
                    //Toast.makeText(this, "Hello", Toast.LENGTH_SHORT).show();
                DialogUtil.showAlert(getApplicationContext(), R.string.message_complete_required_fields);
            }
        });
    }

DialogUtil

  public static void showAlert(Context context, int messageId) {
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setMessage(messageId)
                .setCancelable(true)
                .setPositiveButton(context.getResources().getString(R.string.label_ok), null);
        builder.create().show();
    }

Any suggestions on how to open an alert dialog in onMessageReceived.

Thanks R

ReyAnthonyRenacia
  • 17,219
  • 5
  • 37
  • 56
BRDroid
  • 3,920
  • 8
  • 65
  • 143
  • I'm pretty sure that even, by some miracle you got passed this issue you'd get a `NullPointerException` here - `getApplicationContext()`. You can't (well you can but it won't have the desired behaviour) instantiate `Activity` instances yourself and expect them to work the same as a framework instantiated `Activity`. – Mark Feb 23 '18 at 00:08
  • okay, what is the right way of doing it. – BRDroid Feb 23 '18 at 00:16
  • Personally I wouldn't. I'd send a notification to the system tray, which is the correct way to send notifications. – Mark Feb 23 '18 at 00:22
  • Can you please post line code 38 of SupportActivity.java – Cao Minh Vu Feb 23 '18 at 01:54
  • @CaoMinhVu SupportActicity is of the package 'android.support.v4.app'. if you want that line here it is. line number 38 - public class SupportActivity extends Activity implements LifecycleOwner { – BRDroid Feb 23 '18 at 08:05

2 Answers2

2

Here is my two cents for your issue:

  1. Use Activity context to show dialog or for any UI related stuff for that matter. Also the way you are starting the activity, that's not how its opened. You can choose to show a notification on the top bar and set PendingIntent on it, so that clicking on it opens the desired Activity. Open specific Activity when notification clicked in FCM

  2. Instead of getting a reference to BaseActivity from onMessageReceived, keep them decoupled. Use LocalBroadcastManager or Handler to send message to the Activity to show the dialog. This way if the activity is open it will act on it, else it won't do anything. Check GCM IntentService how to display a pop up on notification receive

Shobhit Puri
  • 25,769
  • 11
  • 95
  • 124
0

The problem is this line: BaseActivity baseActivity = new BaseActivity(); You should not create an instance of Activity, it should be created by system via Intent. When you create the instance by "new" command, it is considered a normal class and all contexts will be wrong.

The idea is to start an activity and let the activity handle the dialog. A quick fix is like this:

@Override public void onMessageReceived(RemoteMessage remoteMessage) {

    if (remoteMessage.getData().size() > 0) {
         Intent intent = new Intent(this, BaseActivity.class);
         startActivity(intent);
    }

}

on BaseActivity.class, call showDialog() in onCreate() method.

Cao Minh Vu
  • 1,900
  • 1
  • 16
  • 21