Как получить данные, отправленные с сервера с помощью fcm, если приложение находится в фоновом режиме?
Я отправляю fcm-уведомления в свое приложение с сервера.
Я отправляю данные с сервера, который содержит user_id. Я получаю этот userId в классе FirebaseMessageService, если приложение находится на переднем плане. Но не получать его, когда приложение находится в фоновом режиме. Поскольку класс FirebaseMessagingService запускается только тогда, когда приложение находится на переднем плане.
Итак, как я могу получить этот идентификатор, когда приложение находится в фоновом режиме?
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
private String mUserId;
private Boolean mUpdateNotification;
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//Displaying data in log
//It is optional
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
String clickAction = remoteMessage.getNotification().getClickAction();
mUserId = remoteMessage.getData().get("user_id");
String title = remoteMessage.getNotification().getTitle();
//Calling method to generate notification
sendNotification(remoteMessage.getNotification().getBody(),clickAction,title);
}
//This method is only generating push notification
//It is same as we did in earlier posts
private void sendNotification(String messageBody,String clickAction,String title) {
mUpdateNotification = true;
Intent intent = new Intent(clickAction);
intent.putExtra("userId",mUserId);
intent.putExtra("updateNotification",mUpdateNotification);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(title)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
EDIT:
Я использую полезную нагрузку данных еще наMessageReceived доза не вызывается, когда приложение находится в фоновом режиме.
public function sendPush($text, $tokens, $apiKey,$user_id)
{
$notification = array(
"title" => "User updated profile.",
"text" => $text,
'vibrate' => 3,
"click_action" => "OPEN_ACTIVITY_2",
'sound' => "default",
'user_id' => $user_id
);
$data = array("user_id" => $user_id);
$msg = array
(
'message' => $text,
'title' => 'User updated profile.',
'tickerText' => 'New Message',
);
$fields = array
(
'to' => $tokens,
'data' => $data,
'notification' => $notification
);
$headers = array
(
'Authorization: key=' . $apiKey,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://android.googleapis.com/gcm/send');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
// echo($result);
// return $result;
curl_close($ch);
}
Может ли кто-нибудь помочь с этим, пожалуйста? Спасибо..
Ответы
Ответ 1
Я вижу. В вашей полезной нагрузке вы используете как полезную нагрузку notification
, так и data
, которая изменяется там, где вы должны получать данные, когда приложение находится в фоновом режиме. В doc, о котором я упоминал в комментариях, вы можете увидеть в сводке, если оба включены в полезную нагрузку:
Данные: в дополнение к намерению.
Более конкретно:
Отправлять уведомления в фоновом приложении
Когда ваше приложение находится в фоновом режиме, Android направляет уведомления на системный трей. Пользователь по нажатию на уведомление открывает панель запуска приложения по умолчанию.
Это включает сообщения, содержащие как полезную нагрузку уведомлений и данных (и все сообщения, отправленные с консоли уведомлений). В этих случаях уведомление доставляется на системный лоток устройства, а полезная нагрузка данных доставляется в дополнение к цели вашей активности запуска.
Я думаю, что этот ответ от @ArthurThompson очень хорошо объясняет:
Когда вы отправляете сообщение уведомления с полезной нагрузкой (уведомлением и данными), а приложение находится в фоновом режиме, вы можете получить данные из дополнительных функций намерения, которые запускаются в результате нажатия пользователем уведомления.
Из образец FCM, который запускает MainActivity при прослушивании уведомления:
if (getIntent().getExtras() != null) {
for (String key : getIntent().getExtras().keySet()) {
String value = getIntent().getExtras().getString(key);
Log.d(TAG, "Key: " + key + " Value: " + value);
}
}
Ответ 2
Зарегистрируйте свою службу в манифесте
<service android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
вы можете проверить, что приложение находится в Foreground или нет
public static boolean CheckAppIsRunningForground(Context mcontext) {
ActivityManager am = (ActivityManager) mcontext
.getSystemService(mcontext.ACTIVITY_SERVICE);
// get the info from the currently running task
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
if (componentInfo.getPackageName().equalsIgnoreCase(<YOUR PACKAGE>)) {
return true;
} else {
return false;
}
}
и добавьте этот код внутри onMessageReceived
Boolean IsForground = CheckAppIsRunningForground(AgentService.this);
if (IsForground) {
//App is FourGround
} else {
sendNotification(remoteMessage.getNotification().getBody(),clickAction,title);
}