4

当我的应用程序处于打开状态并收到通知时,我希望能够立即打开关联的活动,而无需用户点击通知。在前台收到的关于Firebase通知的打开活动

这个问题是非常相似:Open app on firebase notification received (FCM)

但它打开应用程序时,它在后台,我需要做的是,当我的应用程序是在前台。

firebase documentation

通知时,您的应用程序在后台交付。在这个 的情况下,通知被传递到设备的系统托盘。 A 默认情况下,用户点击通知将打开应用程序启动器。带有通知和数据有效负载的消息 ,前台均为背景和 。在这种情况下,通知将传送到 设备的系统托盘,并且数据有效负载将以您的启动程序活动意图的附加组件 传送。

这是我的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); 

    } 

我能够正确地得到通知,但一旦我点击系统托盘通知的活动只有开始implmentation。

有没有办法在不使用前台通话的情况下启动活动?

该方法onMessageReceived()MyFirebaseMessagingServiceextends FirebaseMessagingService在前台正在调用,但活动没有开始。我也试过与国旗FLAG_ACTIVITY_NEW_TASK也没有运气。提前致谢。

回答

3

您可以实现在您的前台活动中注册广播接收器并从onReceiveMessage()方法发送广播。

ForegroundActivity

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(); 
    } 

FirebaseNotificationReceiver

@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); 
    }  
} 

您可以添加一个检查知道如果app is in foreground与否之间做出选择发送通知或发送广播。

+0

ForegroundActivity代码应该放在Myactivity.class(应该打开的活动)还是在不同的活动中? – bankode

+0

在不同的活动。在通知到达的那一刻,用户应该使用它。即:用户打开应用程序并检查一些内容,您可以拥有一个MainActivity类并在那里声明观察者,只要介意用户离开该活动时广播通知将不会被捕获。 – cdiazmo

+0

即使应用程序被终止,此代码是否也能正常工作? –

0

如果你只想设置您的通知,您可以更改此(客户为例例子),

@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());   
    }  
} 

然后像这样(例如)服务器发送消息,唯一的数据(不通知)

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' 
}}; 

REF)

有两种类型的消息在FCM:
- 显示终端AY-消息:这些消息触发onMessageReceived()回调,只有当你的应用程序是在前台
- 数据的消息:论文的消息触发onMessageReceived()回调即使你的应用程序在后台

Two types of messages in FCM

+0

问题很明显,但你确实喜欢你不懂!无益的答案。 – ENSATE

0

我能够调用send()上的PendingIntent来实现这一点:

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, 
       PendingIntent.FLAG_ONE_SHOT); 
try { 
     pendingIntent.send(); 
     } catch (PendingIntent.CanceledException e) { 
      e.printStackTrace(); 
    } 
0
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); 
    } 
} 
+0

欢迎使用StackOverflow,请在答案中添加一些描述,并描述解决问题的哪一部分,以便其他人可以更轻松地理解。 – koceeng

0

创建BroadcastReceiver是处理您的方案的最佳方式。但是你需要知道用户正在使用哪个活动。

创建BroadcastReceiver在每个活动给奇怪的样子。所以创建一个BaseActivity它扩展了Activity。 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) 
}} 

我已经添加了我的kotlin代码。希望你能理解:)

最后你可以从这个BroadcastReceiver

override fun onMessageReceived(message: RemoteMessage) { 
    sendBroadcast(Intent(Constants.ACTIVITY_STUFF)) 
}