Загрузка фрагмента в FCM Push-уведомление нажмите - PullRequest
0 голосов
/ 06 января 2019

Я использую pyFCM на удаленном сервере для отправки уведомлений о событиях в мое приложение. Уведомление также содержит полезные данные, и это необходимо для внесения некоторых изменений в пользовательский интерфейс.

Когда приложение сервера отправляет приложению уведомление, на телефоне появляется всплывающее уведомление, при нажатии которого открывается действие по умолчанию. Кроме того, я переопределил onMessageReceived в службе, расширяющей FirebaseMessagingService, и полезная нагрузка данных затем берется из сообщения и обрабатывается.

Я видел несколько вопросов по SO, например:

  1. Как открыть фрагмент по нажатию push-уведомления
  2. Открыть фрагмент из уведомления, когда приложение в фоновом режиме
  3. Как открыть фрагмент страницы, когда нажимается уведомление в android
  4. Открытие фрагмента при нажатии уведомления в андроиде

Одна из общих черт со всеми вышеупомянутыми вопросами SO заключается в том, что они включают создание уведомления с использованием Notification.Builder , а затем настройку открываемого Activity ( или запуск по onNewIntent в зависимости от от того, является ли это Android: launchMode является "singleTop" в манифесте ). Насколько я понимаю, это будет работать, если использовать FCM для отправки приложению сообщения данных , а не уведомления.

Вопрос (ы)

Что я действительно не понимаю, так это то, как настройка уведомления после получения данных от FCM помогает мне изменить поведение уведомления, полученного от толчка FCM. Это вообще возможно, или я что-то не так понял?

Вторая часть этого вопроса: как мне обработать щелчок пользователя на push-уведомлении, чтобы загрузить определенный фрагмент в моей деятельности (когда я не тот, кто создает фрагмент в приложении - только что полученный через FCM)?

Это текущий код, который работает в моем приложении.

Полученный код onMessage:

@Override
public void onMessageReceived(RemoteMessage remoteMessagenew) {

    this.remoteMessage = remoteMessagenew;
    super.onMessageReceived (remoteMessage);
    database = MyDatabase.getDatabase(getApplication());
    appuser = database.AppDao().getUserDetails(); 


    Log.d(TAG, "onMessageReceived: ");
    Log.d (TAG, "onMessageReceived: #########################################################");
    Log.d (TAG, "onMessageReceived: #########################################################");
    Log.d (TAG, "onMessageReceived: Message Data is : " + remoteMessage.getData ());


    Map messageData = remoteMessage.getData ();

    // Broadcast
    args = new Bundle ();
    int stage = 0 ;
    Log.d (TAG, "onMessageReceived: ");
    if(messageData.containsKey ("otherid")) {
        incidenthandler(messageData);
    } else  if(messageData.containsKey ("itemid")) {
        itemhandler(messageData);
    }
}

Обработчик элементов для обработки данных, которые необходимо обновить на экране приложения

    private void itemhandler(Map messageData) {
    messagebody = remoteMessage.getNotification().getBody();

    if(messageData.containsKey("itemid")) {
        Log.d(TAG, "itemhandler: #######################");
        Log.d(TAG, "itemhandler: #######################");
        Log.d(TAG, "itemhandler: UPDATING");
        Log.d(TAG, "itemhandler: #######################");
        Log.d(TAG, "itemhandler: #######################");

        String item = (String ) messageData.get("itemid");
        JsonParser jsonParser = new JsonParser();
        JsonObject jsonObject = (JsonObject)jsonParser.parse(item);
        item refreshedItem = parseFromJson(jsonObject);
        database.revivDao().upsert(refreshedItem);

    } else {
        // this really shouldn't happen, but putting in a scenario where this does
    // syncing the db with the app
        Log.d(TAG, "itemhandler: #######################");
        Log.d(TAG, "itemhandler: #######################");
        Log.d(TAG, "itemhandler: REFRESHING "); 
        Log.d(TAG, "itemhandler: #######################");
        Log.d(TAG, "itemhandler: #######################");

    // this triggers a call to my intentservice to refresh the db

    Log.d(TAG, "itemhandler: refreshing items");
        Intent intent = new Intent ("refreshitems");
        Bundle clickdata = new Bundle();
        data.putString("item_sub1", item_sub1);
        data.putString("item_sub1", item_sub1);
        intent.putExtra("data", clickdata) ;  // add Bundle to Intent
        localBroadcastManager.getInstance(getApplication()).sendBroadcast(intent); // Broadcast Intent
    }

    String itemid = messageData.get("itemid").toString();
    try{
        Log.d(TAG, "itemhandler: #######################");
        Log.d(TAG, "itemhandler: #######################");
        Log.d(TAG, "itemhandler: sending localbroadcast");
        Log.d(TAG, "itemhandler: #######################");
        Log.d(TAG, "itemhandler: #######################");

    // this is where I try and switch to the screen to display some info - if the app is running

        Intent notificationIntent = new Intent("switchtofragment");
        notificationIntent.putExtra("launchitemfragment", true);
        notificationIntent.putExtra("itemid", itemid);
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        if(localBroadcastManager == null) localBroadcastManager = LocalBroadcastManager.getInstance(getApplication());
        localBroadcastManager.sendBroadcast(notificationIntent);

   // now override the notification to load the fragment on click

        setupNotification(itemid, messagebody);
        notificationManager.notify(1, builder.build());

    } catch (NullPointerException e){
        return;
    }
}

Наконец, функция для обработки уведомления:

private void setupNotification(String housecallid, String message) {
        //Log.d(TAG, "setting up notification");
        String idChannel = ANDROID_CHANNEL_ID;
        Context context = getApplicationContext();

        Intent notificationIntent = new Intent(getApplicationContext(), Reviv.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        notificationIntent.putExtra("housecallid", housecallid);
        notificationIntent.putExtra("launchhousecallfragment", true);
        Bundle extras = new Bundle();
        extras.putBoolean("launchhousecallfragment", true);
        extras.putString("housecallid", housecallid);
        notificationIntent.putExtras(extras);
        notificationIntent.putExtra("data", extras);


        PendingIntent pendingIntent = PendingIntent.getActivity(this,0, notificationIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);

        if(notificationManager == null )
            notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);


        builder = new NotificationCompat.Builder(context, null);
        builder. setSmallIcon(R.drawable.heart)
                .setLargeIcon(BitmapFactory.decodeResource(context.getResources(),
                        R.drawable.heart))
                .setContentIntent(pendingIntent)
                .setContentTitle("Reviv")
                .setContentText(message);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            if(notificationChannel == null) {
                notificationChannel = new NotificationChannel(idChannel, context.getString(R.string.app_name), importance);
                // Configure the notification channel.
                notificationChannel.setDescription("Reviv Housecall Notification");
                notificationChannel.enableLights(true);
                notificationChannel.setLightColor(Color.RED);
                notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
                notificationManager.createNotificationChannel(notificationChannel);
                builder.setChannelId(idChannel);
                builder.setAutoCancel(true);
            }
        } else {
            builder.setContentTitle(context.getString(R.string.app_name))
                    .setPriority(NotificationCompat.PRIORITY_HIGH)
                    .setColor(ContextCompat.getColor(context, R.color.transparent))
                    .setVibrate(new long[]{100, 250})
                    .setLights(Color.RED, 500, 5000)
                    .setAutoCancel(true);
        }
        builder.setContentIntent(pendingIntent);
    }

1 Ответ

0 голосов
/ 06 января 2019
  1. Вы могли бы скорее отправлять data сообщения только вместо отправки push-сообщений + полезной нагрузки и получать все уведомления в onMessageReceived независимо от того, находится ли приложение на переднем плане или в фоновом режиме. Затем вы можете настроить уведомление с помощью написанной вами функции setupNotification , проверить наличие дополнительных функций в начале действия Reviv и соответственно заменить фрагменты.
  2. Я не уверен, но насчет этого подхода с использованием push-уведомлений, но вот предложение: попробуйте проверить, получаете ли вы полезную информацию (проверьте для getIntent().getExtras()), которую вы отправляете с уведомлением push в активности, которая открывается по умолчанию при нажатии на push-уведомление.
...