I have an android app that sends that is supposed to send a push notification to users. When the notification is received by the user, the user taps on the notification and the app is opened and a url is opened in the android webview.
but my app is not receiving any notification.
here is the code
public class MainActivity extends AppCompatActivity {
private WebView webView;
private ProgressDialog dialog;
private BroadcastReceiver mRegistrationBroadcastReciever;
private final String CHANNEL_ID="notificcation";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView=(WebView)findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebChromeClient(new WebChromeClient());
webView.setWebViewClient(new WebViewClient(){
#Override
public void onPageFinished(WebView view, String url) {
if(dialog.isShowing())
dialog.dismiss();
}
});
mRegistrationBroadcastReciever=new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Config.STR_PUSH)){
String message=intent.getStringExtra(Config.STR_MESSAGE);
showNotification("MSG",message);
}
}
};
onNewIntent(getIntent());
}
#Override
protected void onNewIntent(Intent intent) {
dialog=new ProgressDialog(this);
if(intent.getStringExtra(Config.STR_KEY)!=null){
dialog.show();
dialog.setMessage("Please Wait");
webView.loadUrl(intent.getStringExtra(Config.STR_KEY));
}
}
private void showNotification(String title, String message) {
Intent intent =new Intent(getBaseContext(),MainActivity.class);
intent.putExtra(Config.STR_KEY,message);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent=PendingIntent.getActivity(getBaseContext(),0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder=new NotificationCompat.Builder(getBaseContext(),CHANNEL_ID);
builder.setAutoCancel(true)
.setWhen(System.currentTimeMillis())
.setDefaults(Notification.DEFAULT_ALL)
.setSmallIcon(R.mipmap.ic_launcher_round)
.setContentTitle(title)
.setContentText(message)
.setContentIntent(contentIntent);
NotificationManager notificationManager = (NotificationManager)getBaseContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1,builder.build());
}
#Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReciever);
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReciever,new IntentFilter("registration Complete"));
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReciever,new IntentFilter(Config.STR_PUSH));
}
}
The FirebaseMessagingService
public class MyFirebaseMessagingService extends FirebaseMessagingService{
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
handleMessage(remoteMessage.getData().get(Config.STR_KEY));
}
private void handleMessage(String message) {
Intent pushNotification=new Intent(Config.STR_PUSH);
pushNotification.putExtra(Config.STR_MESSAGE,message);
LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);
}
}
The Firebase Instance class
public class MyFirebaseIdService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
super.onTokenRefresh();
String token = FirebaseInstanceId.getInstance().getToken();
sendToServer(token);
}
private void sendToServer(String token) {
}
}
Messages sent via the Firebase console are treated as notification message payloads. From your code, you're only handling data message payloads (remoteMessage.getData() which are probably null. You could include a data message payload along with the notification message contents by adding Advanced Option via the Firebase Console.
Also, FirebaseInstanceIdService has been deprecated. Proceed with using onNewToken() in FirebaseMessagingService.
First you are using LocalBroadcastManager that's only registered if your MainActivity is currently in the foreground.
Secondly, what kind of message are you sending? They could be data or notification messages. If using data I would get rid of the LocalBroadcastManager and declare the showNotification method in MyFirebaseMessagingService so you can directly show the notification from there.
If you are using notification messages. If your app is in the background the push notification would be handled by the System Tray, and the onMessageReceived would only be called if your App is in the foreground.
Take a look at the docs here: https://firebase.google.com/docs/cloud-messaging/android/receive
The most significant part:
onMessageReceived is provided for most message types, with the following exceptions:
Notification messages delivered when your app is in the background. In this case, the notification is delivered to the device’s system tray. A user tap on a notification opens the app launcher by default.
Messages with both notification and data payload, both background and foreground. In this case, 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.
Related
I have receiving GCM push notification message in my mobile successfully. But, I want to make some text update in my app working page.
While receiving push notification, app page automatically need to change text like push notification received and show to any text view, in working page.
Already referred: Updating the UI upon receiving an android push notification
For push notification am using this class to receive notification:
public class GCMBroadcastReceiver extends WakefulBroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
}
}
For MainPage Push notif text showing Activity Page Code:
public void onResume(){
super.onResume() ;
Log.v("tag","onResume working...") ;
broadcast = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(getApplicationContext(), "Receiver...", 1).show();
}
};
LocalBroadcastManager.getInstance(this).registerReceiver(broadcast,new IntentFilter("com.google.android.c2dm.intent.REGISTRATION"));
}
#Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcast);
}
My above code: exactly don't know the mistake in code..
You have to call a local BroadcastReceiver which will be on your current app page.
To do this- Inside your GcmListenerService class after receiving a message on the override method onMessageReceived(String from, Bundle data) you have to call your local BroadcastReceiver on the base of relevant result from inside the method.
When the BroadcastReceiver will call, now show a message or set a text in TextView from inside the local BroadcastReceiver after getting the intent result.
Hope it will help you.
Sir I am trying to send upstream message from my android phone but failed to do so.Don't know where i am wrong.
Here is my code:
public class MainActivity extends AppCompatActivity {
Button button;
private AtomicInteger msgId;
FirebaseMessaging fm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FirebaseMessaging.getInstance().subscribeToTopic("hello");
FirebaseInstanceId.getInstance().getToken();
msgId = new AtomicInteger();
button = (Button) findViewById(R.id.click);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getApplicationContext(),""+msgId,Toast.LENGTH_SHORT).show();
fm = FirebaseMessaging.getInstance();
RemoteMessage message=new RemoteMessage.Builder("<my sender id>#gcm.googleapis.com")
.setMessageId(Integer.toString(msgId.incrementAndGet()))
.addData("my_message", "Hello World")
.addData("my_action", "SAY_HELLO")
.build();
fm.send(message);
}
});
}
}
I had implemented onMessageSent() and onSendError() as according to docs but these methods were never called.Here is my messaging service class:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Log.d("msg", "onMessageReceived: " + remoteMessage.getData().get("message"));
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("test")
.setContentText(remoteMessage.getData().get("message"));
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.notify(0, builder.build());
}
#Override
public void onMessageSent(String s) {
super.onMessageSent(s);
Log.d("fcm", "onMessageSent: message sent");
Toast.makeText(getApplicationContext(), "message:" + s, Toast.LENGTH_SHORT).show();
}
#Override
public void onSendError(String s, Exception e) {
super.onSendError(s, e);
Log.d("fcm", "onSendError: erroe");
Toast.makeText(getApplicationContext(), "error:" + s, Toast.LENGTH_SHORT).show();
}
}
i am trying this from 1 week still don't know where I am wrong.Also there is nothing in logcat.please help.
You have to set TTL at your message, For Example
RemoteMessage message=new RemoteMessage.Builder("<my sender id>#gcm.googleapis.com")
.setMessageId(Integer.toString(msgId.incrementAndGet()))
.addData("my_message", "Hello World")
.addData("my_action", "SAY_HELLO")
.setTtl(86400)
.build();
setTtl(86400) this line is important ,hope it will helps.
In an effort to optimize device resources especially battery the callbacks to onMessageSent and onSendError are batched so you may not receive a callback till you send around 10 or so upstream messages.
See the docs for more.
You need to have an app server running some xmpp server to talk to the Firebase Messaging server.
Be sure to set Time-to-Live on your message. For example, new RemoteMessage.Builder(...).setTtl(<time in sec>). I have not seen this behavior documented in the FirebaseMessagingService and/or Cloud Connection Server (CCS) references.
I am using Parse to do push notifications and the issue I am running into is that while my application is running (either in the foreground or background) the phone's operating system does not show the push notification in the notification bar. What changes to my implementation do I need to make to see the push display on the notification bar?
My extended Application class has the following in onCreate()
// initialize Parse SDK
Parse.initialize(this, Constants.APPLICATION_ID_DEBUG, Constants.CLIENT_KEY_DEBUG);
ParsePush.subscribeInBackground(Constants.CHANNEL, new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Logger.i(TAG, "successfully subscribed to broadcast channel");
} else {
Logger.e(TAG, "failed to subscribe for push: " + e);
}
}
});
ParseInstallation.getCurrentInstallation().saveInBackground();
I have a sign in system for my app, so I am using the ID of the logged in user as the Channel to subscribe users to. So in the first Activity of my app I call the following code snippet in onCreate().
private void registerNotifications() {
List<String> arryChannel = new ArrayList<String>();
arryChannel.add(session.id);
ParseInstallation parseInstallation = ParseInstallation.getCurrentInstallation();
parseInstallation.put("channels", arryChannel);
parseInstallation.saveEventually();
}
I also have a custom receiver that is working. Each time a push is sent out, it is being received by the onPushReceive method, however, I want the push to display in the notification bar.
public class ParsePushReceiver extends ParsePushBroadcastReceiver {
private static final String TAG = ParsePushReceiver.class.getSimpleName();
#Override
public void onPushOpen(Context context, Intent intent) {
Log.i(TAG, "onPushOpen");
}
#Override
protected void onPushReceive(Context context, Intent intent) {
Log.i(TAG, "onPushReceive");
}
}
Thanks in advance!
Just remove the onPushReceive method and the default behaviour will remain (show the notification in the status bar.
You are getting this behaviour because if the application is running the Parse Push notification will call the method onPushReceive that does nothing.
I have figured this out. Although the answer provided by Sandra will make a push notification appear on the notification bar, it is not connected to Parse.
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!");
This causes issues, because if you click on that notification the receiver you create extending ParsePushBroadcastReceiver will not register onPushOpen. My implementation for everything was correct, I only needed to add
super.onPushReceive(context, intent);
That will make the notification appear on the notification bar and also register clicks.
So make sure to make your receiver looks like this (at minimum)
public class ParsePushReceiver extends ParsePushBroadcastReceiver {
private static final String TAG = ParsePushReceiver.class.getSimpleName();
#Override
public void onPushOpen(Context context, Intent intent) {
Log.i(TAG, "onPushOpen");
}
#Override
protected void onPushReceive(Context context, Intent intent) {
Log.i(TAG, "onPushReceive");
**super.onPushReceive(context, intent);**
}
}
I have just implemented Parse push notifications into my app. I want to be able to show the push notification, but i don't want the app to open when the user presses the Push notification. Instead, i just want the notification to be dismissed.
i would imagine it would be handled by the ParsePushBroadcastReciever, but i can't find anything online which fits my purpose.
Here is my subclassed ParsepushBroadcastReciever:
public class Receiver extends ParsePushBroadcastReceiver {
#Override
public void onPushOpen(Context context, Intent intent) {
Log.e("Push", "Clicked");
Intent i = new Intent(context, HomeScreen.class);
i.putExtras(intent.getExtras());
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
In order for you to programatically dismiss a notification you will need to call cancel() using a NotificationManager instance passing in the ID that was passed into notify() on the NotificationManager (since this is what actually pushes the notification into the notification pane). You can't do this using the Parse SDK alone since you will need to take control of the population of notifications yourself.
First you will need to setup a NotificationManager instance then when a notification is ready to be pushed you assign it a value that you can reference later when cancelling like this:
public class MyParsePushBroadcastReceiver extends ParsePushBroadcastReceiver {
NotificationManager mNotificationManager;
int notification_id = 0;
#Override
public void onPushOpen(Context context, Intent intent) {
Log.e("Push", "Clicked");
mNotificationManager.cancel(notification_id)
}
#Override
public void onReceive(Context context, Intent intent) {
mNotificationManager = (NotificationManager)context.getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
super.onReceive(context, intent);
...
}
#Override
protected Notification getNotification(Context context, Intent intent) {
Notification n = super.getNotification(context, intent);
notification_id = intent.getExtras().getInt("NOTIFICATION_TYPE");
mNotificationManager.notify(notification_id, n);
return null;
}
}
So you see by taking control of the NotificationManager (instead of passing it off to the Parse SDK to assign some unknown value) we can know exactly which values to use when calling cancel. I am letting the system build my Notification object (and I get it using super.getNotification()) but you are free to also use a Notification builder to create the notification yourself as well.
I have a subclassed BroadCastReceiver inside my main activity in an android application to deal with changing the GUI when a GCM comes in. All of this works fine.
The one thing that doesn't work is that if this gets called then the user has my app open on his device, and as such I want to clear the notification I entered into the notification center for this incoming GCM. If I put the cancelAll() and cancel(int) lines into my GCMIntentService, then it dismisses the notifications, but I cannot keep it there since I only want to dismiss this notification if the user has my app open. I used both the cancel() and cancelAll() to make sure that I wasn't somehow passing the wrong notification id from the IntentService (I have verified it is correct).
The problem is that there is no error and the notification in the notification center simply won't go away. I have verified that this method is getting called since I get the log entries in logcat.
I referenced this prior answer, but it doesn't work in my implementation for some reason: Starting and stopping a notification from broadcast receiver
My code inside my main activity:
private class NotificationBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.v("Push", "Received Push Notification!");
//Now that the user has opened the app, cancel the notification in the notification center if it is still there
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
final int NOTIFICATION_ID = intent.getIntExtra("notificationId",0);
Log.v("NOTIFICATION_ID",Integer.toString(NOTIFICATION_ID));
mNotificationManager.cancel(NOTIFICATION_ID);
mNotificationManager.cancelAll();
Log.v("Canceled Notifs","Canceled");
}
}
Any ideas why?
A potentially better option is, instead of posting the notification while the app is open, to first detect if the app is visible and, if it is, don't display the notification. You can do this using Intent broadcasts or an event bus like EventBus or Otto.
Example:
public class GCMReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// this is your receiver after gcm has been received
Intent appOpenCheck = new Intent("com.example.IS_APP_OPEN");
// put extras about your notification here...
context.sendOrderedBroadcast(appOpenCheck);
}
}
public class AppNotOpenReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// this is your receiver that will be hit if the app isn't open
// post your notification to the NotificationManager
}
}
Then, in AndroidManifext.xml:
<receiver
android:name=".AppNotOpenReceiver">
<intent-filter>
<action android:name="com.example.IS_APP_OPEN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Finally, in your Activity:
BroadcastReceiver appOpenAlert = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
abortBroadcast(); // prevents notification from going further
// this is your receiver that will be hit if the app is open
// update your ui
}
}
#Override
public void onStart() {
super.onStart();
IntentFilter notificationReceived = new IntentFilter();
notificationReceived.addAction("com.example.IS_APP_OPEN");
notificationReceived.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
registerReceiver(appOpenAlert, notificationReceived);
}
#Override
public void onStop() {
unregisterReceiver(appOpenAlert);
super.onStop();
}