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