当我的应用程序是开放的,我收到通知,我希望能够打开,而无需用户的挖掘上立即通知相关的活动。
这个问题是非常相似:Open app on firebase notification received (FCM)
但它打开应用程序时,它在后台,我需要做的是,当我的应用程序是在前台。
当你的应用程序在后台通知交付。在这种情况下,通知被传递到设备的系统托盘中。在通知用户水龙头打开默认的应用程序启动器。消息既通知和数据有效载荷,无论背景和前景。在这种情况下,通知被传递到设备的系统盘,数据有效载荷在你的发射活动的意图的额外交付。
这是我实现qazxsw的POI
onMessageReceived
我能够正确地得到通知,但一旦我点击系统托盘通知的活动只是开始。
是否有一个启动活动,而不攻的通知,而在前景呢?
从类中的方法@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
sendNotification( remoteMessage);
}
}
/**
* Create and show a simple notification containing the received FCM message.
*
* @param remoteMessage FCM message message received.
*/
private void sendNotification(RemoteMessage remoteMessage) {
Intent intent = new Intent(this, MyActivity.class);
Map<String, String> hmap ;
hmap = remoteMessage.getData();
hmap.get("data_info");
intent.putExtra("data_info", hmap.get("data_info"));
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
}
onMessageReceived()
是MyFirebaseMessagingService
获取调用正确的,而在前台,但活动中,无法启动。我也试图与标志extends FirebaseMessagingService
也没有运气。提前致谢。
你可以做到这一点登记在你前台活动的广播接收器,并从onReceiveMessage()方法发送广播。
ForegroundActivity
FLAG_ACTIVITY_NEW_TASK
火力地堡通知接收器
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Intent myNewActivity = new Intent(this, MyActivity.class);
startActivity(myNewActivity);
}
};
mIntentFilter=new IntentFilter("OPEN_NEW_ACTIVITY");
@Override
protected void onResume() {
super.onResume();
registerReceiver(mReceiver, mIntentFilter);
}
@Override
protected void onPause() {
if(mReceiver != null)
unregisterReceiver(mReceiver);
mReceiver = null;
}
super.onPause();
}
您可以添加一个检查,以了解是否@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
sendNotification( remoteMessage);
Intent broadcast = new Intent();
broadcast.setAction("OPEN_NEW_ACTIVITY);
sendBroadcast(broadcast);
}
}
与否之间做出选择发送通知或发送广播。
我可以通过调用的PendingIntent的send()来实现这一目标:
app is in foreground
(科特林)如果要检查使用内部onMessageReceived这个代码是应用前景或背景
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
try {
pendingIntent.send();
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
然后使用“前台”变量做行动,你需要
var foreground = false
try {
foreground = ForegroundCheckTask().execute(this).get()
} catch (e: InterruptedException) {
e.printStackTrace()
} catch (e: ExecutionException) {
e.printStackTrace()
}
希望它的帮扶..
你可以看到我的全FCMService if (foregroud) { //app in foreground
intent = Intent(this, ChatAdminActivity::class.java)
intent.putExtra("intent_backchat", 1)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK)
pendingIntent = PendingIntent.getActivity(this, Integer.valueOf(random) /* Request code */, intent, PendingIntent.FLAG_UPDATE_CURRENT)
startActivity(intent) // to directly open activity if app is foreground
} else { //app in background
intent = Intent(this, ChatAdminActivity::class.java)
intent.putExtra("intent_backchat", 1)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
pendingIntent = PendingIntent.getActivity(this, Integer.valueOf(random) /* Request code */, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
.....
创建广播接收器是处理您的方案的最佳途径。但是你需要知道正在使用的活动用户。
在每一个活动创建广播接收器提供了一个鬼脸。因此,创建延伸活动一个public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FCM Service";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO: Handle FCM messages here.
// If the application is in the foreground handle both data and notification messages here.
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated.
// IntentFilter filter = new IntentFilter("OPEN_NEW_ACTIVITY");
// registerReceiver(new BroadcastNotification(),filter);
// showNotification(remoteMessage.getNotification().getBody());
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
Log.e("Myname","shdjhfghgh");
}
@Override
public void onCreate() {
super.onCreate();
Intent in= new Intent(this,MainActivity.class);
in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(in);
}
}
。 BaseActivity
将有BaseActivity
码,和所有其他活动来延长这个BroadcastReceiver
。
BaseActivity
我已经加入我的科特林代码。希望你能理解:)
最后,你可以在open class BaseActivity : AppCompatActivity() {
private lateinit var broadcastReceiver: BroadcastReceiver
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(p0: Context?, p1: Intent?) {
if (p1 != null) {
handleBroadcastActions(p1)
}
}
}
}
private fun handleBroadcastActions(intent: Intent) {
when (intent.action) {
Constants.ACTIVITY_STUFF -> {
onHandleActivity()
}
}
}
protected open fun onHandleActivity() {
startActivity(intentFor<YourActivity>())
}
override fun onResume() {
super.onResume()
registerReceiver(broadcastReceiver, IntentFilter(Constants.ACTIVITY_STUFF))
}
override fun onPause() {
super.onPause()
unregisterReceiver(broadcastReceiver)
}}
从BroadcastReceiver
调用此onMessageReceived()
。
FirebaseMessagingService
按照override fun onMessageReceived(message: RemoteMessage) {
sendBroadcast(Intent(Constants.ACTIVITY_STUFF))
}
:
如果你不需要用这是在支持库中可用的LocalBroadcastManager发送广播到组件的应用程序之外,则发送和接收本地广播。该LocalBroadcastManager是(不需要进程间通信)更有效,可以让你避免考虑与其他应用程序能够接收或发送你的广播任何安全问题。本地广播可以在你的应用程序可以作为一个通用的pub / sub事件总线而不全系统广播的任何费用。
所以,喜欢使用LocalBroadcastManager,而不是广播接收器。
在FirebaseMessagingService类,您会收到来自FCM(火力地堡云通讯)和使用的通知:
发送消息给在MainActivity:
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
而在MainActivity创建广播接收器接收消息:
public class AppFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
try {
String messageFrom = remoteMessage.getFrom();
String messageBody = (remoteMessage.getNotification() != null ? remoteMessage.getNotification().getBody() : null);
Map<String, String> messageData = remoteMessage.getData();
NotificationInfo notificationInfo = new NotificationInfo(messageData.get(message));
notifyMainActivity(notificationInfo);
showNotification(notificationInfo);
}
private void notifyMainActivity(NotificationInfo notificationInfo) {
Intent intent = new Intent();
intent.setAction(Constants.BROADCAST_MESSAGE_NOTIFICATION_RECEIVED);
intent.putExtra(Constants.PARAM_NOTIFICATION_INFO, notificationInfo);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
private void showNotification(NotificationInfo notificationInfo) {
Intent intentNotificationClicked = new Intent(this, MainActivity.class);
intentNotificationClicked.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intentNotificationClicked.putExtra(Constants.PARAM_NOTIFICATION_INFO, notificationInfo);
PendingIntent resultIntentNotificationClicked = PendingIntent.getActivity(this, 0, intentNotificationClicked, PendingIntent.FLAG_ONE_SHOT);
String title = "MY APPLICATION";
String message = notificationInfo.message;
Uri notificationSoundURI = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder mNotificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_notification_icon)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setSound(notificationSoundURI)
.setContentIntent(resultIntentNotificationClicked);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
int notificationID = Integer.parseInt(new SimpleDateFormat("HHmmssSSS").format(new Date()));
notificationManager.notify(notificationID, mNotificationBuilder.build());
}
}
下面的代码中引用的类:
public class MainActivity extends AppCompatActivity {
private NotificationBroadcastReceiver mNotificationBroadcastReceiver = null;
private IntentFilter mIntentFilter = null;
@Override
public void onCreate(Bundle savedInstanceState) {
this.mNotificationBroadcastReceiver = new NotificationBroadcastReceiver(this);
this.mIntentFilter = new IntentFilter(Constants.BROADCAST_MESSAGE_NOTIFICATION_RECEIVED);
}
@Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(this.mNotificationBroadcastReceiver, this.mIntentFilter);
}
@Override
protected void onPause() {
if (this.mNotificationBroadcastReceiver != null) {
unregisterReceiver(mNotificationBroadcastReceiver);
this.mNotificationBroadcastReceiver = null;
}
super.onPause();
}
private class NotificationBroadcastReceiver extends BroadcastReceiver {
WeakReference<MainActivity> mMainActivity;
public NotificationBroadcastReceiver(MainActivity mainActivity) {
this.mMainActivity = new WeakReference<>(mainActivity);
}
@Override
public void onReceive(Context context, Intent intent) {
MainActivity mainActivity = mMainActivity.get();
if (mainActivity != null) {
Bundle extras = intent.getExtras();
if (extras != null && extras.containsKey(Constants.PARAM_NOTIFICATION_INFO)) {
NotificationInfo notificationInfo = (NotificationInfo) extras.getSerializable(Constants.PARAM_NOTIFICATION_INFO);
mainActivity.notificationReceived(notificationInfo);
}
}
}
}
public void notificationReceived(@NonNull final NotificationInfo notificationInfo)
{
//handle the notification in MainActivity
}
}
而已!
你需要得到有关您的设备当前的前景应用程序的相关信息。在此基础上,如果启动该活动或发送通知,你可以决定。
为了做到这一点,我会建议是这样的:
public class Constants {
public static final String NOTIFICATION_BROADCAST_RECEIVER_MESSAGE_RECEIVED = "com.mycompany.myapp.NOTIFICATION_RECEIVED";
public static final String PARAM_NOTIFICATION_INFO = "NotificationContent";
}
public class NotificationInfo implements Serializable {
public String message;
public NotificationInfo() { }
public NotificationInfo(String message) { this.message = message; }
}
你必须设置的通知ID,标题,这将在通知中给出的子消息。
您还需要public void onMessageReceived(RemoteMessage remoteMessage) {
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
handleNotification(remoteMessage);
}
}
private void handleNotification(RemoteMessage remoteMessage){
Intent intent = new Intent(this, MyActivity.class);
Map<String, String> hmap ;
hmap = remoteMessage.getData();
hmap.get("data_info");
intent.putExtra("data_info", hmap.get("data_info"));
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Context context = getApplicationContext();
//CHECK IF THIS APP IS IN FOREGROUND
ActivityManager am = (ActivityManager)
AppService.this.getSystemService(ACTIVITY_SERVICE);
// The first in the list of RunningTasks is always the foreground task.
RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0);
String foregroundTaskPackageName = foregroundTaskInfo .topActivity.getPackageName();
if(foregroundTaskPackageName.equals(context.getPackageName()){
//THIS STARTS MAINACTIVITY DIRECTLY IF THE FOREGROUND APP IS THIS APP
startActivity(intent);
}else{
//IF THE FOREGROUND APP ISN'T THIS APP THEN SEND A PENDING INTENT TO OPEN MAIACTIVITY WHEN USER TAP ON NOTIFICATION
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
//CREATE A NOTIFICATION IN THE SYSTEM TRAY
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setContentTitle("TITLE")
.setContentText("SUBMESSAGE")
.setPriority(Notification.PRIORITY_MAX)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setContentIntent(pendingIntent)
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
// notificationId is a unique int for each notification that you must define
notificationManager.notify(notificationId, mBuilder.build());
}
}
允许在应用程序清单以复加。
如果你只想设置您的通知,您可以更改此(客户端的例子),
<uses-permission android:name="android.permission.GET_TASKS" />
然后服务器发送这样的(例如)消息,仅数据(未通知)
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
sendNotification( remoteMessage.getData());
}
}
REF)
有两种类型的FCM消息: - 显示的消息:这些消息触发onMessageReceived()回调,只有当你的应用程序是在前台 - 数据的消息:论文的消息触发,即使你的应用程序在后台onMessageReceived()回调
var message = { //this may vary according to the message type (single recipient, multicast, topic, et cetera)
to: token,
priority: 'high',
content_available: true,
data: {
//you can send only notification or only data(or include both)
message: 'news'
}};