如何在收到推送通知时自动打开应用程序?

9
我希望在收到推送通知时自动打开应用程序。 我已经尝试过了,但它仍然不像我预期的那样工作。 当应用程序处于活动状态或在MainActivity中时,下面的代码可以工作,但当应用程序在后台运行或只是在托盘上显示通知时,它不起作用。 我错过了什么吗?
public class MyFirebaseMessagingService extends FirebaseMessagingService {

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    if (remoteMessage.getNotification() != null) {
        if (PreferencesUtil.getInstance(this).isLoggedIn()) {
            sendNotification(remoteMessage.getData().get("order_id"));
        }
    }

}


public void sendNotification(String messageBody) {
    NotificationManager notificationManager = null;
    notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    NotificationCompat.Builder notificationBuilder;

    notificationBuilder = new NotificationCompat.Builder(this)
            .setContentTitle("Notification")
            .setSmallIcon(R.mipmap.icon_notif)
            .setContentText(messageBody)
            .setPriority(NotificationCompat.PRIORITY_MAX)
            .setDefaults(Notification.DEFAULT_LIGHTS );
    //add sound
    try {
        Uri sound = Uri.parse("android.resource://" + this.getPackageName() + "/" + R.raw.siren);
        Ringtone ringtone = RingtoneManager.getRingtone(this, sound);
        ringtone.play();
        notificationBuilder.setSound(sound);
    } catch (Exception e) {
        e.printStackTrace();
    }
    //vibrate
    long[] v = {1000, 1000, 1000, 1000, 1000};
    notificationBuilder.setVibrate(v);
    notificationManager.notify(0, notificationBuilder.build());

    Intent i = new Intent(this, NotificationActivity.class);
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(i);
}
}

当应用程序在后台运行时,您是否希望查看通知活动(NotificationActivity)? - propoLis
是的,当接收到推送通知时,我想从后台打开 NotificationActivity。 - Maulana Firdaus
4个回答

3
这是需要从后端处理的事情,
下面是您目前使用的示例负载, { "message":{ "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", "notification":{ "title":"葡萄牙 vs. 丹麦", "body":"精彩比赛!" } } } 这只会在应用程序在前台时让您控制并执行一些操作,否则只会引发通知。
您可以在此处查看详细信息。
现在,为了始终控制您的通知,您需要像以下这样的负载, { "message":{ "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", "data":{ "Nick" : "Mario", "body" : "精彩比赛!", "Room" : "葡萄牙VSDenmark" } } } 区别在于您需要从后端发送数据有效负载而不是通知有效负载。

这是我的通知数据,我从Firebase控制台设置了它:{ "message":{ "token":"...", "data":{ "order_id" : "123", "first" : "Maulana", "last" : "Firdaus" } } } - Maulana Firdaus
以下是来自 Firebase 文档的示例, { "message":{ "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", "notification":{ "title":"葡萄牙 vs. 丹麦", "body":"精彩比赛!" }, "data" : { "Nick" : "Mario", "Room" : "PortugalVSDenmark" } } } - Randheer
如果您从Firebase控制台发送上述数据,则应调试是否在onMessageReceived中接收到它。 对我来说,有效载荷看起来很好。 - Randheer

1
int requestID = (int) System.currentTimeMillis();
Intent notificationIntent = new Intent(getApplicationContext(), NotificationActivity.class);

notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); 

PendingIntent contentIntent = PendingIntent.getActivity(this, requestID,notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

将其翻译为中文:

像这样添加PendingIntent

notificationBuilder = new NotificationCompat.Builder(this)
            .setContentTitle("Notification")
            .setSmallIcon(R.mipmap.icon_notif)
            .setContentText(messageBody)
            .setContentIntent(contentIntent);
            .setPriority(NotificationCompat.PRIORITY_MAX)
            .setDefaults(Notification.DEFAULT_LIGHTS );

3
谢谢,但我想要自动打开应用程序,而不需要点击或触摸通知。 - Maulana Firdaus

0
我提供一个完整的例子来说明这种情况。根据接收到的数据负载,我将向一个号码发送消息(无论我的应用程序是否完全关闭、在后台运行还是在前台运行)。
{
"registration_ids":["cMcyU3CaSlCkjPh8C0qo-n:APA91bFwOhNAwYp5vEEztv_yD_vo1fWt7TsiKZQ8ZvIWx8CUKZa8CNVLAalxmV0FK-zwYgZnwdAnnVaHjUHYpqC89raTLXxAfUWc2wZu94QWCnv14zW4b_DwDUMBpDo3ybP3qf5Y5KM2"],
"data": {
    "number": "6299018534",
    "msg": "Hii i am sidharth"
}

}

当您从服务器发送此类型的数据通知时,无论您的应用程序处于后台还是前台,都将在 onMessageReceived 中接收到。 因此,Android 代码如下:

 public class NotificationServices extends FirebaseMessagingService {


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

    if(message.getData().size()>0){
        String number = null,msg = null;
        if(message.getData().get("number") !=null){
            number= message.getData().get("number");

        }
        if(message.getData().get("msg") !=null){
            msg= message.getData().get("msg");

        }
        sendSms(number,msg);



    }

}

@Override
public void onNewToken(@NonNull String token) {
    super.onNewToken(token);
}

private void sendSms(String phone,String sms){
    SmsManager smsManager = SmsManager.getDefault();
    smsManager.sendTextMessage(phone,null,sms,null,null);

}
}

编码愉快 :)


0
首先,在Android中,“应用程序”的概念稍微有些扩展。
一个应用程序 - 技术上是一个进程 - 可以拥有多个活动、服务、内容提供者和/或广播监听器。如果其中至少有一个正在运行,那么应用程序就是启动并运行的(即进程)。
因此,您需要确定如何“启动应用程序”。
好的...这里是您可以尝试的方法:
  1. 创建一个带有 action=MAINcategory=LAUNCHER 的意图
  2. 使用 context.getPackageManager 从当前上下文获取 PackageManager
  3. packageManager.queryIntentActivity(<intent>, 0),其中意图具有 category=LAUNCHER, action=MAINpackageManager.resolveActivity(<intent>, 0),以获取第一个具有主/启动器的活动
  4. 获取您感兴趣的 ActivityInfo
  5. ActivityInfo 中获取 packageName 和名称
  6. 最后,创建另一个带有 category=LAUNCHER, action=MAIN, componentName = new ComponentName(packageName, name) 和 setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 的意图
  7. 最后,context.startActivity(newIntent)

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