Return json object when notification is clicked - android

I'm building an android app which supports push notifications using phonegap/cordova and this plugin. The plugin has an onMessage() method which is triggered whenever a push notification is received, this method returns a json object to my javascript plugin. However I want this method to return the json only when the notification on status bar is clicked.
This is my onMessage() method:
protected void onMessage(Context context, Intent intent) {
String message = "", title = "", type = "";
int msgctn = 0, schoolid = 0, studentid = 0, contentid = 0;
// Extract the payload from the message
Bundle extras = intent.getExtras();
if (extras != null) {
try
{
message = extras.getString("message");
title = extras.getString("title");
type = extras.getString("type");
msgctn = Integer.parseInt(extras.getString("msgctn"));
schoolid = Integer.parseInt(extras.getString("schoolid"));
studentid = Integer.parseInt(extras.getString("studentid"));
contentid = Integer.parseInt(extras.getString("contentid"));
JSONObject json;
json = new JSONObject().put("event", "message");
json.put("message", message);
json.put("type", type);
json.put("contentid", contentid);
json.put("schoolid", schoolid);
json.put("studentid", studentid);
GCMPlugin.sendJavascript( json );
// Send the MESSAGE to the Javascript application
}
catch( JSONException e)
{
Log.e(ME + ":onMessage", "JSON exception");
}
Intent notificationIntent = new Intent(context, App4.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setContentText(message)
.setContentTitle(title)
.setSmallIcon(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? R.drawable.icon : android.R.drawable.ic_dialog_info)
.setAutoCancel(true)
.setContentIntent(contentIntent)
.setWhen(System.currentTimeMillis())
//.setDefaults(Notification.DEFAULT_ALL)
.setLights(-16711681, 2000, 1000)
.setNumber(msgctn)
.setSound(Uri.parse("android.resource://"+ getPackageName() + "/" + R.raw.notifsound));
Notification notification = builder.build();
NotificationManager notificationManager = getNotificationManager(context);
notificationManager.notify(1, notification);
}
I had to create a notification object in order to show it on status bar. When the notification is clicked it calls intent App4, this shows the index.html of my app, but I want to execute some javascript function or return some json object to my app using the payload. Maybe I can call other function to do this, not an intent but I'm new on android world and don't know how to do it.
Can anyone help me please?

What you can do is put the JSON data as extras in the notificationIntent Intent that you are creating. You can do this by calling the putExtras() method of your notificationIntent, or do it manually. Whichever way you do it you need to get the data you want into the notificationIntent as extras.
Then when your App4 activity starts you will need catch the Intent in either onNewIntent() or onCreate() and check to see if the Intent or Bundle has the extras that you want. If it does then you create the JSON object and pass it to your javascript application just like you did in the onMessage() method you pasted.
You will also have to remove the code that sends the JSON object to your javascript application in the onMessage() method.
I hope that helps, it should work but I'm away from my computer and can't actually test the code.

Related

FCM Android - On click Notification - Open webview

Template which I was using : https://github.com/mgks/Android-SmartWebView
Actually, the template has no fcm feature. I added it manually. I referred here so as you look into mainactivity file.
I want to open specific link when user clicks my notification.
My notification Builder is:
// pending implicit intent to view url
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("LINK",link);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, ADMIN_CHANNEL_ID)
.setLargeIcon(BitmapFactory.decodeResource(getBaseContext().getResources(), R.mipmap.ic_launcher)) //set it in the notification
.setSmallIcon(R.mipmap.ic_launcher) //a resource for your custom small icon
.setContentTitle(title) //the "title" value you sent in your notification
.setContentText(message) //ditto
.setContentIntent(pendingIntent)
.setAutoCancel(true) //dismisses the notification on click
.setSound(defaultSoundUri)
.setStyle(new NotificationCompat.BigPictureStyle()
.setSummaryText(message)
.bigPicture(bitmap)
.setBigContentTitle(title));
I tried this in MainActivity:
Intent intent = getIntent();
if (getIntent().getExtras() != null && getIntent().getExtras().getString("link", null) != null && !getIntent().getExtras().getString("link", null).equals("")) {
String url = null;
if (getIntent().getExtras().getString("link").contains("http")) {
url = getIntent().getExtras().getString("link");
} else {
url = "http://" + getIntent().getExtras().getString("link");
}
aswm_view(url, false);
} else {
//Rendering the default URL
aswm_view(ASWV_URL, false);
}
(near lines 250)
But, Nothing is working. Can anyone please help me?
Thankyou.
I think you should use intent.getString() instead of intent.getExtras().getString():
Intent intent = getIntent();
String url = getIntent().getString("link", null)
if (url != null) {
if (!url.startsWith("http")) {
url = "http://" + url;
}
aswm_view(url, false);
} else {
//Rendering the default URL
aswm_view(ASWV_URL, false);
}
According to Intent.getExtras your intent.getExtras() would return null because it was never assigned.
Returns the map of all extras previously added with putExtra(), or null if
none have been added
intent.putExtra("LINK",link);
String url = getIntent().getString("link", null)
This is my mistake. (LINK & link are different.
I spend near 1 weeks for this silly mistake.

Push notifications not opening correct screens

I have an app where I get GCM push notifications in a GcmListenerService(as given in the gcm android sample). Whenever I get the notification, I get some JSON with data related to showing the notification.
Now suppose I get a notification that "someone bookmarked me", for that I get the pk(identifier) of that user and when I click on the notification, it uses the pk received in the push notification to display that user's profile.
The issue : If I get 2 notifications of above mentioned kind, then no matter which notification I click, I always go the profile of the person whose notification I received most recently.
Does getting a notification on top of other, overrides the values of the previous notifications so that only the most recent one is valid? Does that mean I can show only one push notification from an app? I can post the code if that is needed.
Relevant code:
#Override
public void onMessageReceived(String from, Bundle data) {
tinyDB = new TinyDB(this);
if (tinyDB.getBoolean(AppConstants.LOGIN_STATE, false)) {
try {
Log.i("NOTIF", data.toString());
String screen = data.getString("screen");
String dataJson = data.getString("data");
String displayJson = data.getString("display");
String notification_id = data.getString("notif_id");
String priority = data.getString("priority");
String style = data.getString("style");
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
NotificationVal notificationVal = gson.fromJson(displayJson, NotificationVal.class);
String title = notificationVal.getTitle();
String text = notificationVal.getText();
String largeText = notificationVal.getLargeText();
String smallIcon = notificationVal.getSmallIcon();
String largeIcon = notificationVal.getLargeIcon();
Bitmap smallImage = null;
Bitmap largeImage = null;
if (!TextUtils.isEmpty(smallIcon)) {
smallImage = getBitmapFromURL(smallIcon);
}
if ("big_picture".equalsIgnoreCase(style) && (largeImage != null)) {
NotificationCompat.BigPictureStyle notificationStyle = new NotificationCompat.BigPictureStyle();
notificationStyle.setBigContentTitle(title);
notificationStyle.setSummaryText(text);
notificationStyle.bigPicture(largeImage);
Intent intent = NotificationIntentBuilder.get(this, dataJson, screen, smallIcon, largeIcon, notification_id);
TaskStackBuilder stackBuilder = NotificationStackBuilder.get(this, screen, dataJson);
stackBuilder.addNextIntent(intent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
mBuilder.setSmallIcon(R.drawable.white_square);
mBuilder.setAutoCancel(true);
mBuilder.setColor(Color.parseColor("#fac80a"));
mBuilder.setLargeIcon(largeImage);
mBuilder.setContentTitle(title);
mBuilder.setContentText(text);
mBuilder.setContentIntent(resultPendingIntent);
mBuilder.setDefaults(NotificationCompat.DEFAULT_VIBRATE);
mBuilder.setDefaults(NotificationCompat.DEFAULT_SOUND);
mBuilder.setPriority(NotificationCompat.PRIORITY_HIGH);
mBuilder.setStyle(notificationStyle);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (notification_id != null) {
mNotificationManager.cancel(Integer.parseInt(notification_id));
mNotificationManager.notify(Integer.parseInt(notification_id), mBuilder.build());
}
} else {
Log.i("GCM", "Dummy Notification");
}
} catch (Exception e) {
Log.i("NOTIF", "An exception occurred");
}
}
}
Other internal codes:
public class NotificationStackBuilder {
public static TaskStackBuilder get(Context context, String screen, String data) {
if ("IMAGE".equalsIgnoreCase(screen)) {
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(ImageActivity.class);
return stackBuilder;
} else {
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(NewHomeActivity.class);
return stackBuilder;
}
}
}
public class NotificationIntentBuilder {
public static Intent get(Context context, String data, String screen, String smallIcon, String largeIcon, String notificationId) {
if ("IMAGE".equalsIgnoreCase(screen)) {
String pk = "";
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(data);
if (jsonObject.has("pk")) {
pk = jsonObject.getString("pk");
}
} catch (JSONException e) {
e.printStackTrace();
}
Intent intent = new Intent(context, ImageActivity.class);
intent.putExtra("ID", pk);
intent.putExtra("notificationId", notificationId);
return intent;
} else if ("GALLERY".equalsIgnoreCase(screen)) {
String pk = "";
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(data);
if (jsonObject.has("pk")) {
pk = jsonObject.getString("pk");
}
} catch (JSONException e) {
e.printStackTrace();
}
Intent intent = new Intent(context, GalleryActivity.class);
intent.putExtra("ID", pk);
intent.putExtra("notificationId", notificationId);
return intent;
} else {
return new Intent(context, NewHomeActivity.class);
}
}
}
Edit This issue is not happening with two notifications of different type(opening different activities), it is only happening with notifications opening the same screen.
Edit 1 Here is the value received in the push notification:
Bundle[{google.sent_time=1469254984538, priority=0, screen=IMAGE, data={"pk":650}, style=big_picture, google.message_id=0:1469254984541527%e07f0e28f9fd7ecd, notif_id=4267, display={"large_icon":"https:\/\/d2r0rrogy5uf19.cloudfront.net\/photos\/971c03f8-6a5d-30a3-9e49-0ab416cb8fa0.jpg","small_icon":"","text":"Random hi5'd your photo to 'Diwali'","title":"random","large_text":""}, collapse_key=do_not_collapse}]
This one has notificationId as 4267, now suppose I get another notification for same screen, with notificationId say, 4268, then when I log the notificationId received in the Image screen, I get 4268 on opening both the notifications.
Edit 2 I guess the issue is related to PendingIntent.FLAG_UPDATE_CURRENT. Here is what is written in the documentation:
Flag indicating that if the described PendingIntent already exists, then keep it but replace its extra data with what is in this new Intent.
This is what was happening. The contents of intent extras were getting over-written by the latest notification's intent extras. So, I tried using FLAG_ONE_SHOT, but with that I am able to open the old intent but noting opens when I click the latest intent.
I want both notifications to be on the push notification list and that both of them should the respective screens with different values of intent extras.
You need to have unique request code for each notification or else it will be replaced with new one.
An excerpt from PendingIntent documentation :
The last intent in the array represents the key for the PendingIntent.
In other words, it is the significant element for matching (as done
with the single intent given to getActivity(Context, int, Intent,
int), its content will be the subject of replacement by send(Context,
int, Intent) and FLAG_UPDATE_CURRENT, etc. This is because it is the
most specific of the supplied intents, and the UI the user actually
sees when the intents are started.
So replace the below line:
PendingIntent resultPendingIntent = stackBuilder. getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
Assuming notification_id is unique integer, just replace it like below:
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(Integer.parseInt(notification_id)
, PendingIntent.FLAG_UPDATE_CURRENT);

Send PUSH notification Android when fetching data is true

I am trying to make a very little application. My app will fetch an url:
example.com/response.json
when this response "true" my app will send a notification message:
Your thing is ready! Let's see.
But I have no idea how to make it? Do I need a Timer or what?
I found this method:
private static void generateNotification(Context context, String message) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.ic_launcher, "Message received", System.currentTimeMillis());
// Hide the notification after its selected
notification.flags |= Notification.FLAG_AUTO_CANCEL;
//adding LED lights to notification
notification.defaults |= Notification.DEFAULT_LIGHTS;
Intent intent = new Intent(context, MessageReceivedActivity.class);
intent.putExtra("payload", payload);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
notification.setLatestEventInfo(context, "Message", "New message received", pendingIntent);
notificationManager.notify(0, notification);
}
But how to check every 5min the response and send the notification?
download this file using i.e. HttpURLConnection or HttpClient inside AsyncTask doInBackground method. example of fetching data:
HttpGet reqest = new HttpGet(yourURL);
HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(reqest);
String result = EntityUtils.toString(response.getEntity());
for parsing JSON use JSONObject(String json) passing result (and/or optionally JSONArray if needed)
if result matches your expectations use Toast.makeText(...) or Notifications (example here)

Android Notifications, loads only the latest intent when there are more than one notifications

I have an app which has 4 layers/stack, something like,
HomePage >> DetailPage >> MapPage >> ChatPage
I managed to create notifications whenever I received different chat messages (note that each conversation has its unique id, say ChatId)
for different conversation, I will create a notification using ChatId as the requestCode in the pendingIntent
The problem I am facing is that, whenever I received more than 1 notification, say ChatId1 comes first, followed by ChatId2. Then when I clicked on the ChatId1's notification, it will launch the latest intent which is ChatId2, making the conversations loaded in ChatPage are conversations of ChatId2.
Question is, how can I make it so that, when I clicked on ChatId1's notification, it loads messages of ChatId1, and when click on ChatId2, it loads messages of ChatId2.
Below is the snippet of the code where I create my notifications
public void createLocalNotification(String meetingIdLong, String countryCode, String phoneNumber, String contactName, String chatMessage) {
// Prepare intent which is triggered if the
// notification is selected
Intent intent = new Intent(this, ChatLog.class);
long L = Long.parseLong(meetingIdLong);
int a = Integer.parseInt(meetingIdLong);
intent.putExtra("meetingId", L);
Intent intent1 = new Intent(this, HomePage.class);
Intent intent2= new Intent(this, MeetingDetailPage.class);
intent2.putExtra("meetingId", L);
Intent intent3 = new Intent(this, MapPage.class);
intent3.putExtra("meetingId", L);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(ChatLog.class);
stackBuilder.addNextIntent(intent1);
stackBuilder.addNextIntent(intent2);
stackBuilder.addNextIntent(intent3);
stackBuilder.addNextIntent(intent);
PendingIntent pIntent = stackBuilder.getPendingIntent(a, PendingIntent.FLAG_UPDATE_CURRENT);
String notificationSound = _defPrefs.getString("pref_notification_tone", "");
NotificationCompat.Builder noti = new NotificationCompat.Builder(this)
.setContentTitle(contactName)
.setContentText(chatMessage)
.setSmallIcon(R.drawable.noti_smallicon)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.noti_smallicon))
.setSound(Uri.parse(notificationSound))
.setDefaults(Notification.DEFAULT_VIBRATE)
.setNumber(++numberMsg)
.setAutoCancel(true)
.setContentIntent(pIntent);
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
String[] events = new String[6];
events [numberMsg - 1] = new String(chatMessage);
// Sets a title for the Inbox style big view
inboxStyle.setBigContentTitle(contactName);
inboxStyle.setSummaryText(numberMsg + " new message(s)");
for (int i=0; i < events.length; i++) {
inboxStyle.addLine(events[i]);
}
noti.setStyle(inboxStyle);
String isChatOpen, isChatOpenId;
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
isChatOpen = preferences.getString("isChatOpen","");
isChatOpenId = preferences.getString("isChatOpenId","0");
if (!isChatOpenId.equals(meetingIdLong))
{
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(a, noti.build());
}
}
Use
intent.setAction(Long.toString(System.currentTimeMillis()));
for each your Intent you want to be unique. Its just a dummy action, but it helps.

sending an audio file via push notification in android

Is it possible to send an audio file as a push notification in android ? What i want to do is that the user can record his voice as a message and then that message should be delivered to all the users with that app as a push notification . is it possible ?
According to below document, CGM / C2DM / Push Notification can send only 4KB data, So, you can not send audio files via push notification,
http://developer.android.com/guide/google/gcm/c2dm.html
"Apps can use "messages with payload" to deliver messages of up to 4 Kb"
But you can send http url of any audio file, in mobile app will receive audio file link via cgm message and download audio file using http connection.
The other way to do it, is use a module that has already implemented this for you. Technically you do the exact same thing that is described here, however with a single API call to providers like mBlox (http://developer.mblox.com), you'll be able to post your content and the devices you want to target, the hosting of the content, and the translation to a URL are being done for you, as well as sending the actual push notification.
Again, technically, it's the same as previous answers, however, for your personal integration it might be a quicker way to get to market.
There is a Way, we can send a audio url in data from FCM. After that we can parse and sent to another activity.
In FIREBASE SERVICE
JSONObject object = null;
try {
String data = remoteMessage.getData().toString();
Map<String, String> params = remoteMessage.getData();
object = new JSONObject(params);
} catch (Exception e) {
Log.e("FCM err 1", e.getMessage());
}
sendNotification(this, remoteMessage.getNotification().getBody(), remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getClickAction(), object);
PUSH NOTIFICATION FUNCTION
public static void sendNotification(Context context, String Message, String Title, String ClickAction, JSONObject object) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
final String CHANNEL_ID = "KRB";
if (Build.VERSION.SDK_INT >= 26) { // Build.VERSION_CODES.O
NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, "KRB_channel", NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(mChannel);
}
// intent = Home
Intent intent = new Intent(ClickAction);
try {
Log.e("FCMurl", object.getString("url"));
Log.e("FCMtype", object.getString("type"));
intent.putExtra("url", object.getString("url"));
intent.putExtra("type", object.getString("type"));
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
} catch (Exception e) {
// Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
Log.e("FCM err", e.getMessage());
}
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0 /* Request code */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.icon_logo)
.setColor(Color.parseColor("#531E6C")) // small icon background color
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.icon_sfach))
.setContentTitle(Title)
.setContentText(Message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setPriority(Notification.PRIORITY_MAX)
.setDefaults(Notification.DEFAULT_ALL)
.setContentIntent(pendingIntent);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
In activity
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
String url;
if(bundle != null){
url = bundle.getString("url");
MediaPlayer mediaplayer = new MediaPlayer();
try {
mediaplayer.setDataSource(url);
mediaplayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaplayer.prepareAsync();
mediaplayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mediaplayer.start();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}

Categories

Resources