我在onMessageReceived中无法使用AlertDialog。

3

我试图在onMessageReceived中使用AlertDialog,但是出现了这个错误。

05-04 11:27:40.038 30721-31424/com.xxx.xxx E/AndroidRuntime: FATAL EXCEPTION: pool-4-thread-1
                                                                              Process: com.xxx.xxx, PID: 30721
                                                                              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.Dialog.<init>(Dialog.java:108)
                                                                                  at android.app.AlertDialog.<init>(AlertDialog.java:125)
                                                                                  at android.app.AlertDialog$Builder.create(AlertDialog.java:967)
                                                                                  at android.app.AlertDialog$Builder.show(AlertDialog.java:986)
                                                                                  at com.xxx.xxx.util.FirebaseMessagingService.optionalAlert(FirebaseMessagingService.java:78)
                                                                                  at com.xxx.xxx.util.FirebaseMessagingService.onMessageReceived(FirebaseMessagingService.java:38)
                                                                                  at com.google.firebase.messaging.FirebaseMessagingService.zzl(Unknown Source)
                                                                                  at com.google.firebase.messaging.FirebaseMessagingService.zzJ(Unknown Source)
                                                                                  at com.google.firebase.messaging.FirebaseMessagingService.handleIntent(Unknown Source)
                                                                                  at com.google.firebase.iid.zzb$1.run(Unknown Source)
                                                                                  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
                                                                                  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
                                                                                  at java.lang.Thread.run(Thread.java:818)

这是我的代码:
public class FirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        super.onMessageReceived(remoteMessage);
        String msg=remoteMessage.getNotification().getBody();
        Map<String, String> params = remoteMessage.getData();
        String Valuekey = remoteMessage.getData().get("key");

        if (Valuekey.equals("true")) {
            optionalAlert();
        }else {
            Util.Alert(this,getString(R.string.ConsignmentNoFound));
        }

       // Util.Alert(getBaseContext(),msg);
    }

    private void optionalAlert () {


        AlertDialog.Builder adb = new AlertDialog.Builder(this);

        TextView textView = new TextView(this);
        textView.setText(getString(R.string.ConsignmentFound));
        textView.setTextSize(24);
        adb.setCustomTitle(textView);


        //adb.setTitle(getString(R.string.ConsignmentFound));


        adb.setIcon(android.R.drawable.ic_dialog_alert);


        adb.setPositiveButton("Si", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {

                Intent nextActivity = new Intent(FirebaseMessagingService.this, MainActivity.class);
                nextActivity.putExtra("act", "PinValidate");
                startActivity(nextActivity);

            } });


        adb.setNegativeButton("No", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {


            } });
        adb.show();
    }

}
5个回答

3
我知道现在回复已经太晚了,但这可能会帮助到某些人。在FirebaseMessagingService中显示AlertDialog是可能的。你所需要做的就是创建一个活动并将其主题设置为对话框,就像我在清单文件中使用的主题一样。

enter image description here

在 Manifest.xml 文件中。
<activity android:name=".View.StartCompaignDialogActivity"
    android:label="Start Compaign!"
    android:theme="@style/Theme.AppCompat.Dialog"></activity>

StartCompaignDialogActivity.java

public class StartCompaignDialogActivity extends AppCompatActivity implements View.OnClickListener {
    Dialog dialog;
    Button yes,no;
    String TAG = "StartCompaignDialogActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start_compaign);

        AlertDialog.Builder builder = new  AlertDialog.Builder(this);
        View view = getLayoutInflater().inflate(R.layout.activity_start_compaign_dialog,null);
        builder.setView(view);
        AlertDialog dialog = builder.create();
        dialog.show();
        yes = (Button) view.findViewById(R.id.start_compaign_yes);
        no = (Button)view. findViewById(R.id.start_compaign_no);
        yes.setOnClickListener(this);
        no.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        if (v.getId() == R.id.start_compaign_yes){
            Log.e(TAG,"customer press yes.");

        }else if (v.getId() == R.id.start_compaign_no){
            Log.e(TAG,"customer press no.");
        }
    }
}

activity_start_compaign_dialog.xml

   <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#fff"
    tools:context=".View.StartCompaignDialogActivity">

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:cardBackgroundColor="#fff">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:textSize="22dp"
                android:textStyle="bold"
                android:textColor="#c5282828"
                android:text="Start Compaign!"
                android:fontFamily="@font/sanomat_regular"/>

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:gravity="center"
                android:textSize="@dimen/h5"
                android:textStyle="bold"
                android:textColor="#87000000"
                android:text="Ambassador is waiting for your compaign to start. Do you want to start your compaign ?"
                android:lineSpacingExtra="3dp"
                android:fontFamily="@font/sanomat_regular"/>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="25dp"
                android:orientation="horizontal"
                android:weightSum="2">

                <Button
                    android:id="@+id/start_compaign_yes"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:layout_marginLeft="20dp"
                    android:layout_marginRight="20dp"
                    android:layout_marginBottom="10dp"
                    android:layout_alignParentBottom="true"
                    android:background="@color/yes"
                    android:textColor="#f5f1f1f1"
                    android:textSize="22dp"
                    android:text="YES"
                    android:fontFamily="@font/sanomat_bold"/>

                <Button
                    android:id="@+id/start_compaign_no"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:layout_marginLeft="20dp"
                    android:layout_marginRight="20dp"
                    android:layout_marginBottom="10dp"
                    android:layout_alignParentBottom="true"
                    android:background="@color/no"
                    android:textColor="#f5f1f1f1"
                    android:textSize="22dp"
                    android:text="No"
                    android:fontFamily="@font/sanomat_bold"/>

            </LinearLayout>

        </LinearLayout>

    </android.support.v7.widget.CardView>

</RelativeLayout>

这是您想要显示警示对话框的代码。只需在onMessageReceived方法中启动活动即可。警示对话框将出现在用户面前。
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        Intent intent = new Intent(FirebaseMessage.this,StartCompaignDialogActivity.class);
        startActivity(intent);
}

你好,为什么要设置两次布局?1)setContentView(R.layout.activity_start_compaign_dialog); 2)builder.setView(view);? - Bruno
builder.setView将视图附加到AlertDialog,而setContentView将视图/布局附加到活动。 - Shahzad Afridi
抱歉造成困惑,布局文件名与活动分开。已更正。 - Shahzad Afridi

3

这肯定有效

package pkg.name

import pkg.name.DisplayAlert
import android.content.Intent
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
class CloudMsg:  FirebaseMessagingService() {
    override fun onNewToken(token: String) {}

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        val mDisplayAlert = Intent(this, DisplayAlert::class.java)
        mDisplayAlert.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        mDisplayAlert.putExtra("title",  remoteMessage.notification?.title)
        mDisplayAlert.putExtra("body",  remoteMessage.notification?.body)
        startActivity(mDisplayAlert)
    }

    override fun onCreate() {}

}

package pkg.name

import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity

class DisplayAlert : AppCompatActivity() {
    internal var title: String? = null
    internal var body: String? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        b = intent.extras
        if (b != null) {
            title = b!!.getString("title")
            body = b!!.getString("body")
            val builder: AlertDialog.Builder = AlertDialog.Builder(this)
            builder.setTitle(title)
            builder.setIcon(R.drawable.store)
            builder.setMessage(body)
                .setCancelable(false)
                .setPositiveButton("Yes") { dialog, id ->
                    finish()
                }
            val alertDialog = builder.create()
            alertDialog.show()
        }
    }
    companion object {
        var b: Bundle? = null
    }
}

<service
    android:name=".CloudMsg"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

<activity
    android:name=".DisplayAlert"
    android:label="@string/app_name"
    android:theme="@style/Total_Translucent">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

<style name="Total_Translucent" parent="Theme.AppCompat.DayNight.NoActionBar">
    <item name="android:windowBackground">@color/transparent</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="colorPrimaryDark">@color/transparent</item>
</style>

 <color name="transparent">@android:color/transparent</color>

enter image description here


0

你不能在接收器中显示对话框,因为接收器具有不用于显示任何用户界面的不同“上下文”。

如果你想显示对话框,则需要启动具有对话框主题的活动。


1
尽管这仍然适用,FirebaseMessagingService是一个服务。 - Submersed

0

您必须在特定线程上执行影响UI的操作。鉴于活动实例,您可以访问一个方便的方法来做到这一点:

activity.runOnUiThread(new Runnable() {
    public void run() {
        // perform ui operations...
    }
});

我应该在哪里实现这个功能?是在FirebaseMessagingService类中还是在当前活动中? - julian david
获取当前正在运行的活动实例。 - kailoon

-1
在你的 MyFirebaseMessagingService 类中:-
public void onMessageReceived(RemoteMessage remoteMessage) 
{

        context = this;
        Log.d(TAG, "From: " + remoteMessage.getFrom());
        Log.d(TAG, "Notification Message getMessageId: " + remoteMessage.getMessageId());
        Log.d(TAG, "Notification Message getMessage: " + remoteMessage.getData().get("message"));
        Log.d(TAG, "Notification Message getAction: " + remoteMessage.getData().get("action"));
        Log.d(TAG, "Notification Message template_id: " + remoteMessage.getData().get("template_id"));
        Log.d(TAG, "Notification Message notification_user_id: " + remoteMessage.getData().get("notification_user_id"));
        Log.d(TAG, "Notification Message joined_user_id: " + remoteMessage.getData().get("sender_id"));

        //Calling method to generate notification
        sendNotification(remoteMessage.getData().get("message"), remoteMessage.getData().get("action"),
                remoteMessage.getData().get("template_id"),
                remoteMessage.getData().get("notification_user_id"),
                remoteMessage.getData().get("sender_id"));
    }

private void sendNotification(final String messageBody, String messageAction, String templateId, String notiUserId, String sender_id) {
            if (ApplicationClass.getInstance().getCurrentClass() != null) {
                //Let this be the code in your n'th level thread from main UI thread
                Handler h = new Handler(Looper.getMainLooper());
                h.post(new Runnable() {
                    public void run() {
                        Common.displayAlert(ApplicationClass.getInstance().getCurrentClass(), messageBody);
                    }
                });
            }

}

在普通类中创建一个方法来显示对话框。
 public static void displayAlert(final Context context, String respMsg) {
        try {
            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            builder.setCancelable(false);
            builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    Intent splashIntent = new Intent(context, MobileNoVerificationActivity.class);
                    splashIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                    context.startActivity(splashIntent);
                }
            });
            builder.setTitle("" + context.getString(R.string.app_name));
            builder.setMessage(respMsg);
            builder.create().show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

希望这能对你有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接