You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 12(API 31)下Notification Builder操作按钮无响应求助

Android 12(API 31)通知操作按钮无响应问题

我开发了一款聊天应用,在API 31以下的Android系统中,通知的接听电话操作按钮可正常工作,但在Android 12(API 31)上,仅无操作的通知能正常显示,带操作按钮的通知点击无响应。相关代码如下,求解决:


FirebaseService.java

@Override
public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);

    boolean cancelNotification = false;

    Intent intent = new Intent(this, MainActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

    Map<String, String> params = remoteMessage.getData();
    JSONObject data = new JSONObject(params);

    PendingIntent pendingIntent;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
        pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_MUTABLE);
    } else {
        pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
    }

    String channel_id = getNotificationData(data, "channel");

    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channel_id)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(getNotificationData(data, "title"))
            .setContentText(getNotificationData(data, "body"))
            .setAutoCancel(true)
            .setContentIntent(pendingIntent);

    if(channel_id.equals("cll2") && getNotificationData(data, "call_action").equals("open")){
        playCallSound(this);

        if(WindowUtil.isAppOnBackground(this) || isScreenOff()){
            ArrayList<String> par = new ArrayList<>();

            par.add("call_channel");
            par.add("call_type");
            par.add("call_token");
            par.add("call_peer");

            String callType = getNotificationData(data, "call_type");

            if(callType.equals("3") || callType.equals("4")){
                par.add("call_group_name");
                par.add("call_group_caller");
            }

            Intent receiveCallAction = new Intent(this, CallReceiver.class);
            receiveCallAction.putExtra("action", "ANSWER");

            Intent cancelCallAction = new Intent(this, CallReceiver.class);
            cancelCallAction.putExtra("action", "DECLINE");

            for (String s : par) {
                receiveCallAction.putExtra(s, getNotificationData(data, s));
                cancelCallAction.putExtra(s, getNotificationData(data, s));
            }

            notificationBuilder.setOngoing(true);

            receiveCallAction.setAction("RECEIVE_CALL");
            cancelCallAction.setAction("CANCEL_CALL");

            PendingIntent receiveCallPendingIntent = PendingIntent.getBroadcast(this, 1200, receiveCallAction, PendingIntent.FLAG_UPDATE_CURRENT);
            PendingIntent cancelCallPendingIntent = PendingIntent.getBroadcast(this, 1201, cancelCallAction, PendingIntent.FLAG_UPDATE_CURRENT);

            notificationBuilder
                    .addAction(R.drawable.ic_baseline_call_24_green, "Answer", receiveCallPendingIntent)
                    .addAction(R.drawable.ic_baseline_call_red_24, "Decline", cancelCallPendingIntent);
        }else{
            cancelNotification = true;
        }
    }if(channel_id.equals("cll2") && getNotificationData(data, "call_action").equals("end_timeout")){
        stopRinging();
    }else if(channel_id.equals("ntf1")){
        if(UserUtil.IS_CHAT_ACTIVITY){
            cancelNotification = true;
        }

        if(!cancelNotification){
            playNotificationSound(this);
        }
    }

    if(!cancelNotification){
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            notificationBuilder.setDefaults(Notification.DEFAULT_VIBRATE);
            NotificationChannel channel = new NotificationChannel(channel_id,
                    getString(R.string.app_name), NotificationManager.IMPORTANCE_HIGH);
            channel.enableLights(true);
            channel.enableVibration(true);
            mNotificationManager.createNotificationChannel(channel);
        }

        mNotificationManager.notify(1000, notificationBuilder.build());
    }
}

CallReceiver.java(Broadcast Receiver)

@Override
public void onReceive(Context context, Intent intent) {
    if (intent != null && intent.getExtras() != null) {
        String action = intent.getStringExtra("action");

        // Perform the action
        performClickAction(context, action, intent.getExtras());

        // Close the notification after the click action is performed.
        NotificationManager mNotificationManager = (NotificationManager)
                context.getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.cancel(1000);

        // Stop the ringtone
        stopRinging();
    }
}

AndroidManifest.xml

<service
        android:name=".services.FirebaseService"
        android:exported="true">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

    <receiver
        android:name=".receiver.CallReceiver"
        android:exported="false"
        android:enabled="true">
        <intent-filter>
            <action android:name="CALL_RECEIVER" />
        </intent-filter>
    </receiver>

问题解决办法

1. 适配Android 12的PendingIntent标记

Android 12(API 31)及以上版本要求创建PendingIntent时必须指定FLAG_MUTABLE或FLAG_IMMUTABLE,你当前创建广播PendingIntent时未添加该标记,导致点击无响应。修改FirebaseService中创建广播PendingIntent的代码:

PendingIntent receiveCallPendingIntent;
PendingIntent cancelCallPendingIntent;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
    receiveCallPendingIntent = PendingIntent.getBroadcast(this, 1200, receiveCallAction, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
    cancelCallPendingIntent = PendingIntent.getBroadcast(this, 1201, cancelCallAction, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
} else {
    receiveCallPendingIntent = PendingIntent.getBroadcast(this, 1200, receiveCallAction, PendingIntent.FLAG_UPDATE_CURRENT);
    cancelCallPendingIntent = PendingIntent.getBroadcast(this, 1201, cancelCallAction, PendingIntent.FLAG_UPDATE_CURRENT);
}

2. 修正广播Action不匹配问题

代码中给广播Intent设置的Action是RECEIVE_CALL和CANCEL_CALL,但Manifest里注册的是CALL_RECEIVER,两者不匹配导致广播无法被接收,任选一种方式修改:

方式一:修改代码中的Action

receiveCallAction.setAction("CALL_RECEIVER");
cancelCallAction.setAction("CALL_RECEIVER");

方式二:修改Manifest中的Intent Filter

<receiver
    android:name=".receiver.CallReceiver"
    android:exported="false"
    android:enabled="true">
    <intent-filter>
        <action android:name="RECEIVE_CALL" />
        <action android:name="CANCEL_CALL" />
    </intent-filter>
</receiver>

3. 优化通知渠道创建逻辑(可选)

当前每次发送通知都重复创建通知渠道,建议将渠道创建逻辑移到Application的onCreate方法中,避免重复操作。


内容的提问来源于stack exchange,提问作者Aditya Rizqi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 09:40:32