I want to take data of whatsapp message coming in my Android from Notification bar Is it possible to get this
You need to create a service to listen to incoming notifications by extending NotificationListenerService in which, you'll have a method call back :
#Override
public void onNotificationPosted(StatusBarNotification sbn) { .... }
Where you'll get all the data inside that particular notification.
If you want only WhatsApp Notifications, you can add a filter
which matches the package name like: sbn.getPackageName().matches("com.whatsapp")
Here is more information about StatusBarNotification
for getting the title/content(message) of the notifications you'll need to extract them from the bundle Bundle bundle = statusBarNotification.getNotification().extras; you can extract message from the bundle using something like this:
private String getDataFromBundle(Bundle bundle) {
Object data = bundle.get("android.bigText");
if (data == null) {
data = bundle.get("android.text");
}
return data == null? "" :data.toString();
}
PS: don't forget to register your service in manifest..
Related
can i intercept notifications when my app is closed?
I need for set badge with this library ShortcutBadger
Thanks.
There are 3 types of notifications:
notification: Can be send from the web console or any backend, it has predefines values. If the app is open the behaviour is customizable on onMessageRecieve if the app is closed triggers a default notification.
data: a key value pair, only Strings. Can be send from any backend. The behaviour is always defined in onMessageReceived method.
notification and data: Combination of previous it will have the behaviour of a notification, the data will be available as extras once the notification is clicked in the default launcher activity. Can be send from the web console or any backend.
A push is a json called Payload which contains those objects:
payload: {
data: {...}
}
Yes, you can send yourself a data type notification it will always do what you write in the onMessageReceived method inside the MessagingService.
This doc should help you
https://firebase.google.com/docs/cloud-messaging/concept-options?hl=es-419
If you dont have a server use Functions.
Since the default notification wont be shown, you will probably want to show your own.
If you want to also show a notification then the NotificationCompat class must be called from inside onMessageReceived. The visual notification is not related to the push message, in fact, a visual notification can be triggered by pressing a button.
For creating a visual notification, the best approach is to let Android Studio do it for you. Second click on the packages where your activities .java are, new, then selecet ui-component and there is the notification. It will create a basic template of a notification. Then use those methods inside onMessaReceived passing the info that has to be show to the user.
The docs about the class
https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html
And you will probably find this error
NotificationCompat.Builder deprecated in Android O
In case you never solved this, the problem is not how you are implementing it within your app, but how the JSON data payload is being sent. See this question and the respective answers for why you are not receiving the messages while they are in the background.
Very short summary is, if you are receiving the notification payload, it will never trigger in the background. If you receive the data payload without notification, you can parse and perform actions while the app is in the background.
do you mean it?
public class AppFcmMessagingsService extends FirebaseMessagingService {
private static final String TAG = "FirebaseMessageService";
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
try {
if(remoteMessage.getData().size() > 0) {
final JSONObject jsonObject = new JSONObject(remoteMessage.getData().toString());
Log.d(TAG,"remoteMessage = " + jsonObject.toString());
int badgeCount = 1;
ShortcutBadger.applyCount(getApplicationContext(), badgeCount);
}
} catch (Exception e) {
Log.e(TAG, "onMessageReceived: ", e);
}
if(remoteMessage.getNotification() != null) {
int badgeCount = 1;
ShortcutBadger.applyCount(getApplicationContext(), badgeCount);
Log.d(TAG, "notification body : " + remoteMessage.getNotification().getBody());
}
}
}
The FirebaseMessagingService has the method onMessageReceived() which we should override to handle notifications, but this only works when the app is in Foreground.
To handle notifications even when the app is in background, I used to override the handleIntent, to just call the onMessageReceived().
In FirebaseMessagingService 11.6.0, the method handleIntent became final, with that said, I can't override it as I was doing.
How should I handle notifications when my app is in background in the 11.6.0?
public class NotificationsListenerService extends FirebaseMessagingService {
private static final String TAG = "NotificationsListenerService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage)
String notifyData = remoteMessage.getData().get("notifData");
if(notifyData.contains("|")){
String[] itens = notifyData.split("\\|");
notifyData = itens[0];
}
String notifyType = remoteMessage.getData().get("notifType");
String title = remoteMessage.getData().get("title");
String message = remoteMessage.getData().get("body");
if(!isAppInForeground(App.getContext())){
sendNotification(title, message, notifyData, notifyType);
}
}
#Override
public final void handleIntent(Intent intent) {
...
this.onMessageReceived(builder.build());
...
}
private void sendNotification(String messageTitle, String messageBody, String notifyData, String notifyType) {
...
}
//Detect if app is in foreground
private boolean isAppInForeground(Context context) {
...
}
}
It's not intended for anyone to override handleIntent(). That's why it was made final. Also, you'll notice that it's completely missing from the javadocs - that's intentional.
If you want to handle a message in any circumstance (both foreground and background), use onMessageReceived(). The javadoc for that method says:
Called when a message is received.
This is also called when a notification message is received while the
app is in the foreground. The notification parameters can be retrieved
with getNotification().
This should work for data messages, but not notification messages sent from the console. Notification messages have different delivery behavior. See the documentation about message types and how to handle them.
I'd add that in FirebaseMessagingService 11.8.0 docs, it is stated in https://firebase.google.com/docs/cloud-messaging/android/receive that if a notification has a data payload it will call onMessageRecieved() when the app is in the foreground, and if the app is in the background the notification and data payload are delivered in the extras of the intent of your launcher Activity.
So, this means you need to decide how to handle the notification in two places, depending on whether the user is actively using the app or if it is in the background.
As you have seen yourself, if you receive the notification while the app is in the foreground, onMessageReceived() is called and you handle the notification there.
When the app is launched from the background, you have 2 options:
1: By default, the notification is sent to your system tray, and when it is clicked it opens your main activity, passing the data (what would have been remoteMessage.getData() in onMessageReceived()) to your activity as intent extras. You can handle the extras in your main activity like so and decide what to do with them, for instance check for a key value and launch a related intent.
// [START handle_data_extras]
if (getIntent().getExtras() != null) {
for (String key : getIntent().getExtras().keySet()) {
Object value = getIntent().getExtras().get(key);
Log.d(TAG, "Key: " + key + " Value: " + value);
}
}
You can decide what intent to open on-click if you add an intent-filter in your app manifest and a designated "click_action" value in your notification, and then handle the intent extras in the designated activity. See https://stackoverflow.com/a/39665485/3746204
I'd also suggest checking the firebase messaging sample app for ideas: https://github.com/firebase/quickstart-android/tree/master/messaging
i have the same problem after update firebase library version.
i think the easiest way is downgrade firebase library again (i use 11.4.2) and handleIntent() still works !
I am using Firebas mesaging service class. and Its working properly when app is running in foreground but when i clear this application from recent i am not able to access the push notification data for setting it on textview.
I want to store data in database when app is running in background.
I had Used Database to store the value directly but its not working.
public void onMessageReceived(RemoteMessage message) {
database=new SQLiteHelper(getApplicationContext());
database.open();
String image = message.getNotification().getIcon();
String title = message.getNotification().getTitle();
String text = message.getNotification().getBody();
String sound = message.getNotification().getSound();
int id = 0;
database.addQuotes(text,"Xyz");
}
In MainActivity.java in Oncreate method
Bundle extras = getIntent().getExtras();
if (extras != null) {
final String message = extras.getString("message");
quote_text.setText(message);
Toast.makeText(this, "A", Toast.LENGTH_SHORT).show();
}
But message shows null data.
based on this:
I want to store data in database when app is running in background
The service calls which extends FirebaseMessagingService has a method called onMessageReceived which is called when a push notification is received on the front-end (app) add your message to DB there!
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
.....
// parse and add your message to Db here!
Normally when your app is in the background, Android directs notification messages to the system tray. A user tap on the notification opens the app launcher by default.
This includes messages that contain both notification and data payload (and all messages sent from the Notifications console). In these cases, the notification is delivered to the device's system tray, and the data payload is delivered in the extras of the intent of your launcher Activity.
But you can refer this answer on stackoverflow if you want to get notification data-messages in your app while in background.
You may also refer this
i am having a group chat feature.every person in the group will receive the push(even the sender of the message).
if the person has opened the group i.e the chatting area is visible, then i want that the push does not show up in the notification bar and it directly update the chat (which i am showing in a listview ).
Initially the chat history i get from web service (when the user open the chat area)
Hope i am able to make you guys clear with what i want to achieve .thanks in advance
First of all, when you get message in onMessage() of GCMIntentService, send brodcast. Like,
Intent i = new Intent();
i.setAction("appendChatScreenMsg");
i.putExtra("sender_id", b.getString("sender_id"));
i.putExtra("message", b.getString("message"));
i.putExtra("time", getCurrentTime());
i.putExtra("date", getCurrentDate());
this.sendBroadcast(i);
Next, Make BroadcastReceiver in your Chat activity or Chat Fragment. Like,
BroadcastReceiver appendChatScreenMsgReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle b = intent.getExtras();
if (b != null) {
int totalItems = adapter.getCount() - 1;
ChatModel model = new ChatModel("" + sharedPreferences.getString(VariableBag.USERID, ""), ""+ b.getString("sender_id"), "" + b.getString("message"), b.getString("date"), b.getString("time"));
arrChat.add(model);
if (adapter != null) {
if (lstChat.getLastVisiblePosition() == totalItems) {
adapter.notifyDataSetChanged();
lstChat.setSelection(adapter.getCount());
} else {
adapter.notifyDataSetChanged();
}
} else {
adapter = new ChatAdapter(getActivity());
lstChat.setAdapter(adapter);
adapter.notifyDataSetChanged();
lstChat.setSelection(adapter.getCount());
}
}
}
};
Next, Register BroadcastReceiver in onCreate(). Like
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActivity().registerReceiver(this.appendChatScreenMsgReceiver, new IntentFilter("appendChatScreenMsg"));
}
Next, unregisterReceiver in onDestroy(). Like,
#Override
public void onDestroy() {
super.onDestroy();
getActivity().unregisterReceiver(appendChatScreenMsgReceiver);
}
Explanation :
1.) When message is received in GCMIntentService(), first of all, check weather
you are in chat screen or not.
2.) If you are in chat screen, broadcast your message using Intent and Broadcast.
3.) Now, Create your BroadcastReceiver() in chat screen.
4.) Register your BroadcastReceiver() in onCreate() and unregister in onDestroy().
5.) When message is broadcast and you are in chat screen, this broadcast receiver get your bundle.
6.) Now Whatever you want to do.
7.) If you are not in chat screen, then show respected message in notification. Don't broadcast.
Note: Be sure in which screen you are currently.
I think you should use Observer Design Pattern.
set a listener where you display messages and in your service where you get your messages from server check for listener, if listener wasnt null call a update method from listener and update your list else show notification.
example of this patern :
http://www.vogella.com/tutorials/DesignPatternObserver/article.html
I have successfully implemented the push notification tutorial for Android. Once the notification is received it will immediately perform an action based on the json objects passed via the BroadcastReceiver.
However we would like that the action only be performed once the user clicks the push notification alert in the notification tray. Is this possible? From the tutorials we can choose which activity is opened via the subscribe method.
I am trying to determine when a particular push notification is clicked to launch the app. I am sending the pushes with a custom action and receiving them fine. When the notification is clicked to open the app for the first time, I receive the action and push notification data in the extras. However, once the app is already open / backgrounded, the extras never change. If I open the app from a different push notification OR open the app just from the app icon, the extras remain the same as the original notification that opened the app (or no extras if the app was opened originally just by the icon).
This is my code in onResume() method of my activity
Intent intentNotification = getIntent();
Bundle extras = intentNotification.getExtras();
if (extras!=null) {
String jsonData = extras.getString( "com.parse.Data" );
System.out.println("Message Data : "+jsonData);
}
Any one please help me on this problem..
I also went through the same situation while using Xtify for push notification
I applied a simple logic of creating static variable according to the need. when the specific operation id completed . in my case user registers , then I would make the static variable to empty (public static String MY_GLOBAL_VARIABLE=""). Unless the user doesn't register the variable contains the value
try to implement this logic ...
hope this can help to at least to start.
Try this....
public static String MY_JSON_DATA;
Intent intentNotification = getIntent();
Bundle extras = intentNotification.getExtras();
if (extras!=null) {
MY_JSON_DATA=extras.getString( "com.parse.Data" );
System.out.println("Message Data : "+MY_JSON_DATA);
}
// when open the app , use the value from MY_JSON_DATA and after clear it like MY_JSON_DATA=""
add this method into your Activity which is push notification open
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Bundle extras = intent.getExtras();
setIntent(intent);
if (extras!=null) {
String jsonData = extras.getString( "com.parse.Data" );
System.out.println("New Notification Data : "+jsonData);
String msg;
try {
JSONObject jMsg=new JSONObject(jsonData);
if (jMsg.has("alert")) {
msg=jMsg.getString("alert");
Util.SaveToSharedPref(LoginActivity.this, Constant.ShaPreNotification, Constant.ShaPreNotfMessage, msg);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
and onRecevie() method call one custom function which body is same as onNewIntent()
This is important because when app is completely closed i.e it is remove from recent apps /apps history at that time on receive method is called so it getting notification message.
and other time it call onNewIntent() method