0

I saw that this is not an uncommon topic, and I have tried to read other posts, but I don't know how to apply it to my app. In my app, I am sending Push Notifications through PostMan, which then opens different activities according to the flags I'm setting. I would like to send also different links to the notification so when the user clicks on it, it will open a browser. In other words, I would like to have both the activity flags when the notification is dedicated to an activity, and the URL, when the notification contains a specific link.

I have seen from the answers from a previous post that one solution would be so set an intent like this:

Intent notificationIntent = new Intent(Intent.ACTION_VIEW);

notificationIntent.setData(Uri.parse("http://www.google.com"));
PendingIntent contentIntent = PendingIntent.getActivity(contexta, 0, notificationIntent, 0);
notification.setLatestEventInfo(contexta, contentTitle, contentText, contentIntent);
mNotificationManager.notify(970970, notification);

but as far as I can see, this has www.google.com set by default. How can I make it so that it opens the specific link I send by PostMan? I assume that I need to introduce the above code into my IF conditions somehow (as in here), but how?

The code that I have for the PushNotifications is given below:

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.google.firebase.messaging.RemoteMessage;

import org.json.JSONException;
import org.json.JSONObject;

public class MyFirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService {
  private static final String TAG = "FirebaseMessagingServic";

  public MyFirebaseMessagingService() {}

  @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());
      try {
        JSONObject data = new JSONObject(remoteMessage.getData());
        String jsonMessage = data.getString("extra_information");
        Log.d(TAG, "onMessageReceived: \n" +
          "Extra Information: " + jsonMessage);
      } catch (JSONException e) {
        e.printStackTrace();
      }
    }

    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
      String title = remoteMessage.getNotification().getTitle(); //get title
      String message = remoteMessage.getNotification().getBody(); //get message
      String click_action = remoteMessage.getNotification().getClickAction(); //get click_action

      Log.d(TAG, "Message Notification Title: " + title);
      Log.d(TAG, "Message Notification Body: " + message);
      Log.d(TAG, "Message Notification click_action: " + click_action);

      sendNotification(title, message, click_action);
    }
  }

  @Override
  public void onDeletedMessages() {

  }

  private void sendNotification(String title, String messageBody, String click_action) {
    Intent intent;
    if (click_action.equals("EVENIMENTE")) {
      intent = new Intent(this, Evenimente.class);
      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    } else if (click_action.equals("PRIMA_PAGINA")) {
      intent = new Intent(this, MainScreenActivity.class);
      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

    } else {
      intent = new Intent(this, MainScreenActivity.class);
      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    }

    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */ , intent,
      PendingIntent.FLAG_ONE_SHOT);

    Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
      .setSmallIcon(R.drawable.app_logo_final)
      .setContentTitle("App")
      .setContentText(messageBody)
      .setAutoCancel(true)
      .setLights(Color.RED, 3000, 3000)
      .setSound(defaultSoundUri)
      .setVibrate(new long[] {
        1000,
        1000,
        1000,
        1000,
        1000
      })
      .setContentIntent(pendingIntent);


    NotificationManager notificationManager =
      (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    notificationManager.notify(0 /* ID of notification */ , notificationBuilder.build());
  }
}

So, I have the click_action set, as was also suggested in some other posts so I guess this is where the link can be sent from PostMan, but how? Can anyone please help me with this? Thank you!

CuriousPaul
  • 449
  • 8
  • 20
  • I can't imagine why it should be hard to achieve if you have already sent actions inside message body. Can't you just send some links as well, then parse and put that data inside intent of pending intents? – Ranjan Jan 25 '18 at 17:08
  • It's hard because I am new to this. It makes sense what you just wrote, but I am not sure where to use this `Uri.parse()`. I can also clearly see that it have so be like this `Intent notification Intent = new intent(Intent.ACTION_VIEW); notificationIntent.setData(Uri.parse("http://www.google.com"));` Do I just need to get rid of www.google.com ? – CuriousPaul Jan 25 '18 at 17:14
  • So you want to open a browser when you send a link and open your activities when there is no link(but action will be there)? – Ranjan Jan 25 '18 at 17:27
  • Yes! That is correct. – CuriousPaul Jan 25 '18 at 17:33

1 Answers1

1

Let me just explain few things. Intents can have actions assigned to them and activities can have intent filters. Intent filters is like saying that whenever this kind of intent is broadcasted by system, I, an activity, am willing to handle it. These intent filters are written inside the manifest file. So your activity will look something like this. These kind of intents are called implicit intents.

<activity
    android:name=".MainActivity" >
    <intent-filter>
        <action android:name="com.example.MY_ACTION" />
    </intent-filter>
</activity>

When I want to start this activity from an implicit intent, it'll be done this way.

Intent intent = new Intent("com.example.MY_ACTION");

Now coming to your question, you can improve certain things in your code. You can include intent filters in your activities inside Manifest file. So you won't have to put those if conditions.

Just like your custom intent action, browsers have default action which is Intent.ACTION_VIEW. Now you just send correct actions in your message from postman, create implicit intents for those actions and you are done.

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.google.firebase.messaging.RemoteMessage;

import org.json.JSONException;
import org.json.JSONObject;

public class MyFirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService {
  private static final String TAG = "FirebaseMessagingServic";

  public MyFirebaseMessagingService() {}

  @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());
      try {
        JSONObject data = new JSONObject(remoteMessage.getData());
        String jsonMessage = data.getString("extra_information");
        Log.d(TAG, "onMessageReceived: \n" +
          "Extra Information: " + jsonMessage);
      } catch (JSONException e) {
        e.printStackTrace();
      }
    }

    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
      String title = remoteMessage.getNotification().getTitle(); //get title
      String message = remoteMessage.getNotification().getBody(); //get message
      String click_action = remoteMessage.getNotification().getClickAction(); //get click_action
      String uri = remoteMessage.getNotification().getLink(); //parsing url

      Log.d(TAG, "Message Notification Title: " + title);
      Log.d(TAG, "Message Notification Body: " + message);
      Log.d(TAG, "Message Notification click_action: " + click_action);
      Log.d(TAG, "Message Notification uri: " + uri);

      sendNotification(title, message, click_action, uri);
    }
  }

  @Override
  public void onDeletedMessages() {

  }

  private void sendNotification(String title, String messageBody, String click_action, Uri uri) {
    Intent intent;
    /*if (click_action.equals("EVENIMENTE")) {
      intent = new Intent(this, Evenimente.class);
      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    } else if (click_action.equals("PRIMA_PAGINA")) {
      intent = new Intent(this, MainScreenActivity.class);
      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

    } else {
      intent = new Intent(this, MainScreenActivity.class);
      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    }*/

    //If conditions can be replaced with this. Not sure why wrote last else condition. If you want to start MainScreenActivity when there is no action or the action is PRIMA_PAGINA, you could simply write direct else.
    if(uri != null) {
      intent = new Intent(Intent.ACTION_VIEW);
      intent.setData(uri);
    } else {
      intent = new Intent(click_action);
      //click_action will be "EVENIMENTE"/"com.example.EVENIMENTE" for Evenimente.class, PRIMA_PAGINA for MainScreenActivity.class
    }

    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */ , intent,
      PendingIntent.FLAG_ONE_SHOT);

    Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
      .setSmallIcon(R.drawable.app_logo_final)
      .setContentTitle("App")
      .setContentText(messageBody)
      .setAutoCancel(true)
      .setLights(Color.RED, 3000, 3000)
      .setSound(defaultSoundUri)
      .setVibrate(new long[] {
        1000,
        1000,
        1000,
        1000,
        1000
      })
      .setContentIntent(pendingIntent);


    NotificationManager notificationManager =
      (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    notificationManager.notify(0 /* ID of notification */ , notificationBuilder.build());
  }
}

Update and include intent-filter for your activities as mentioned above. Intent-filter should exactly be like click_action you are going to send in the fcm message.

Ranjan
  • 1,096
  • 10
  • 22
  • Thank you so much for the nice answer! I'm implementing it now and did all the changed in manifest. Do I need to define the symbol method `getUrl()` as `public String getUrl() { return url; } public void setUrl(String url) { this.url = url; }`? I get Cannot resolve method. – CuriousPaul Jan 25 '18 at 18:22
  • It looks like everything is fine with the code except this part with getUrl. I don't know where to define it – CuriousPaul Jan 25 '18 at 18:34
  • You have to define it. Similar to what you did for `getClickAction()` – Ranjan Jan 25 '18 at 18:55
  • Nope. This is the one. https://firebase.google.com/docs/reference/android/com/google/firebase/messaging/RemoteMessage.Notification I think I need to use getLink() – CuriousPaul Jan 25 '18 at 18:59
  • I think this is the definition of url `Uri url = remoteMessage.getNotification().getLink();` But now I can't use `sendNotification(title, message,click_action, url);`, right? – CuriousPaul Jan 25 '18 at 19:01
  • RemoteMessage is an fcm object. It has this getLink() method that you can use to send and receive url I guess. You url will change from String to Uri since this method returns an Uri. Here https://firebase.google.com/docs/reference/android/com/google/firebase/messaging/RemoteMessage.Notification – Ranjan Jan 25 '18 at 19:02
  • sendNotification is your own method. You can change the parameter type in definition and it will work. – Ranjan Jan 25 '18 at 19:03
  • `private void sendNotification(String title, String message, String click action, Uri uri){}` – Ranjan Jan 25 '18 at 19:05
  • Yes. I have added it now. Let's see how it goes. Thank you! – CuriousPaul Jan 25 '18 at 19:05
  • I also added " " for url, as it didn't work with url. `intent.setData(Uri.parse("url"));` – CuriousPaul Jan 25 '18 at 19:07
  • It isn't working :( I think here is the problem `intent.setData(Uri.parse(url));`, as it says I need a string instead of `url` – CuriousPaul Jan 25 '18 at 19:15
  • Nope. I can't seem to figure it out. Darn – CuriousPaul Jan 25 '18 at 19:31
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/163917/discussion-between-ranjan-and-curiouspaul). – Ranjan Jan 26 '18 at 03:18