I have this code to generate a notification from inside the GCM-Service:
private void sendNotification(Bundle extras) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
String notification_type = extras.getString("type");
NotificationManager notificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, extras.getString("message"), when);
String title = this.getString(R.string.app_name);
Intent notificationIntent = new Intent(this, InvitationActivity.class);
if ( notification_type != null && notification_type.equals("invitation"))
{
notificationIntent = new Intent(this, InvitationActivity.class);
notificationIntent.putExtra("lobby_id", Integer.valueOf(extras.getString("messagedata", "0")));
} else {
notificationIntent = new Intent(this, MainActivity.class);
}
// set intent so it does not start a new activity
//notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
// Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent =
PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(this, title, extras.getString("message"), intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
The Problem is that MainActivity starts if I click on the notification, however if
notificationIntent = new Intent(this, InvitationActivity.class);
is called and I tap on the notification, nothing seems to happen, no error, no activity is launched. This only occurs with InvitationActivity, Mainactivity is working fine.
InvitationActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_invitation);
lobby_id = getIntent().getIntExtra("lobby_id", 0);
EDIT:
AndroidManifest.xml:
<activity
android:name=".activities_fragments.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activities_fragments.InvitationActivity"
android:label="#string/title_activity_invitation"
android:theme="#android:style/Theme.Holo.Dialog">
</activity>
The strange thing is, if I start InvitationActivity from within MainActivity it works as expected, but not from inside the GCMService.
Add
android:exported="true"
Inside your invitationActivity tag like this:
<activity
android:name=".activities_fragments.InvitationActivity"
android:label="#string/title_activity_invitation"
android:exported="true"
android:theme="#android:style/Theme.Holo.Dialog">
</activity>
This will resolve your issue
Related
When push notification is received while the app is not running and the user presses on notification, it just disappears and the log says:
2019-10-22 12:42:45.747 23260-23260/de.app.test.staging E/FirebaseMessaging: Notification pending intent canceled
Here is the SplashActivity that is supposed to be launched as a Launcher Activity:
<activity
android:name="de.app.test.login.SplashActivity"
android:screenOrientation="portrait"
android:exported="true"
android:theme="#style/Theme.AppCompat.Light.NoActionBar.FullScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
What can the issue be here?
For anyone looking for an answer, the back-end was sending the "click_action" to notification, therefore there was no intent filter for that Activity.
For me the click_action is "OPEN_ACTIVITY_1" so I just added one more intent-filter to my SplashActivity like this:
<intent-filter>
<action android:name="OPEN_ACTIVITY_1" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
you need to set pendingIntent object in notificationBuilder instance like
mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID);
Intent intent = new Intent(context, TargetActivity.class));
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
builder.setContentIntent(pendingIntent);
Please note that CHANNEL_ID is for build version greater or equal to Oreo
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CHANNEL_ID = createNotificationChannel(CHANNEL_ID, "channelName");
}
#RequiresApi(Build.VERSION_CODES.O)
private String createNotificationChannel(String channelId, String channelName) {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
String description = "description";
NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_NONE);
channel.setLightColor(Color.BLUE);
channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
mNotificationManager.createNotificationChannel(channel);
return channelId;
}
Forground app:
You need a PendingIntent to open app.
Try this:
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
Intent notificationIntent = new Intent(context, SplashActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
If Activity is in background or closed then notification message is shown in the notification center for app launcher activity.
You can use a BroadcastReceiver class. When you close the app, broadcast can listen this action. So, if you create a BroadcastReceiver class, you don't take this problem.
public class ClosedBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(new Intent(context, HomePage.class));
} else {
context.startService(new Intent(context, HomePage.class));
}
}
}
More Information:
https://firebase.google.com/docs/cloud-messaging/android/receive
I have read (almost) all the other questions related to the same problem here on StackOverflow.
The problem is the usual: when I tap on a Notification published by my app, the related Activity is not started. This is the code:
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
... String json is prepared ...
Intent intentForActivity = new Intent(this, MyActivity.class);
Bundle extras = new Bundle();
extras.putString(Activity.KEY_JSON, json);
intentForActivity.setFlags(
Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_CLEAR_TASK);
intentForActivity.putExtras(extras);
PendingIntent pendingIntent =
PendingIntent.getActivity(this,
0,
intentForActivity,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
... various builder methods for icon, title, message ...
builder.setContentIntent(pendingIntent);
notificationManager.notify(NOTIFICATION_ID++, builder.build());
Some notes:
I have tried various flags and permutations, nothing changed;
I had to put PendingIntent.FLAG_UPDATE_CURRENT for having the String json in extras updated, otherwise Android kept using the first one.
This is what I have been using and it worked for me. The code is self explanatory.
private void showNotification(final String title, String text, int ID, boolean showTimeStamp) {
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) //Use a builder
.setContentTitle(title) // Title
.setContentText(text) // Message to display
.setTicker(text).setSmallIcon(R.drawable.ic_notif_small) // This one is also displayed in ticker message
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.bulb)); // In notification bar
Intent resultIntent = new Intent(this, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
//mBuilder.addAction(R.drawable.bulb_small, "OK", resultPendingIntent);
Notification notification = mBuilder.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_SHOW_LIGHTS | Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE;
long time = 0;
if (showTimeStamp)
Calendar.getInstance().getTimeInMillis();
else
time = android.os.Build.VERSION.SDK_INT >= 9 ? -Long.MAX_VALUE : Long.MAX_VALUE;
notification.when = time;
mNotificationManager.cancel(ID);
mNotificationManager.notify(ID, notification);
}
And also add this android:launchMode="singleTask" to your Manifest where you have your main activity
Example:
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:launchMode="singleTask" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
I am using push notifications in Android. When I receive a push notification and click on it it launchs an activity as i want , but if this activity it's already opened nothing happened , the activity keeps the old data.
AndroidManifest.xml
<activity
android:name=".Detail"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/title_activity_detail"
android:launchMode="singleTop"
android:parentActivityName=".Home"
android:theme="#style/Theme.AppCompat.Light.DarkActionBar" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="ma.via.marocagenda.Home" />
</activity>
GCMIntentService.java
public class GCMIntentService extends GCMBaseIntentService {
...
private static void generateNotification(Context context, String message) {
//int icon = R.drawable.abc_ic_go;
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
String title = context.getString(R.string.app_name);
Intent notificationIntent = new Intent(context, Detail.class);
// put extra for details
notificationIntent.putExtra("id", VAL_TAG_ID);
notificationIntent.putExtra("titre", VAL_TAG_TITRE);
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
notification.defaults |= Notification.DEFAULT_LIGHTS;
notificationIntent.addFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK );
//PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
}
what can be wrong ?
You Can override onNewIntent() in your Activity to get the Latest Intent From the Notification.
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent.hasExtra("key")){
//do your Stuff
}
}
You may use Local broadcasts from your service whenever a push notification arrives.
For how to use Local broadcasts read here https://stackoverflow.com/a/8875292/826657
Let your activity register for this broadcast action, and when a push notification is received, update the activity from onReceive().
Also, being more specific using ActivityManager you can check that if you activity is on top, if true send the broadcast also, else just show the notification.
Read here for how to find the current foreground activity.
https://stackoverflow.com/a/4753333/826657
I am using GCM in my application and also using NotificationManager to Create a Notification whenever GCM message is received.Till now everything is working perfectly and GCM message is showing correctly in Notification area, but when I click on the notification it should start an activity of my application which will display the message detail which is not happening. Every-time I click on notification it does not start any activity and it remains as is.My code for creating Notification is :
private void sendNotification(String msg) {
SharedPreferences prefs = getSharedPreferences(
DataAccessServer.PREFS_NAME, MODE_PRIVATE);
mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, WarningDetails.class);
Bundle bundle = new Bundle();
bundle.putString("warning", msg);
bundle.putInt("warningId", NOTIFICATION_ID);
intent.putExtras(bundle);
// The stack builder object will contain an artificial back stack for
// the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(WarningDetails.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(intent);
PendingIntent contentIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.weather_alert_notification)
.setContentTitle("Weather Notification")
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg);
String selectedSound = prefs.getString("selectedSound", "");
if (!selectedSound.equals("")) {
Uri alarmSound = Uri.parse(selectedSound);
mBuilder.setSound(alarmSound);
} else {
Uri alarmSound = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
mBuilder.setSound(alarmSound);
}
if (prefs.getBoolean("isVibrateOn", false)) {
long[] pattern = { 500, 500, 500, 500, 500, 500, 500, 500, 500 };
mBuilder.setVibrate(pattern);
}
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
I updated my code to support Preserving Navigation when Starting an Activity just like it happens in Gmail application using the Android developers website since then it stopped working.Someone Please guide me what I am missing or doing wrong in this code.
My problem got solved I just have to add PendingIntent.FLAG_ONE_SHOT flag as well , so I replaced :
PendingIntent contentIntent = stackBuilder
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
to
PendingIntent contentIntent = stackBuilder
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT
| PendingIntent.FLAG_ONE_SHOT);
I encountered the same issue and resolved it by adding android:exported="true" to the activity declaration in AndroidManifest.xml.
Here you just passed your Intent into pendingintent: see below
Intent notificationIntent = new Intent(context, Login.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
and set this contentintent into your Notification:
Notification noti = new NotificationCompat.Builder(context)
.setSmallIcon(icon_small)
.setTicker(message)
.setLargeIcon(largeIcon)
.setWhen(System.currentTimeMillis())
.setContentTitle(title)
.setContentText(message)
.setContentIntent(**contentIntent**)
.setAutoCancel(true).build();
This may help you.
if you launch the intended activity using Action String dont forget to add
<intent-filter>
<action android:name="YOUR ACTION STRING"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
inside <activity></activity> tag
The activity that you want to launch has to be designated as a LAUNCHER activity in your manifest - otherwise it won't launch via a Pending Intent. Add the following to your in the AndroidManifext.xml
<activity
...
android:exported="true">
<intent-filter>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Otherwise you will need to use an Activity that is already designated as a LAUNCHER (such as your MAIN activity)
Do some thing like this on generateNotification() method ..
Replace your activity with Splash.Java class in it.
/**
* Issues a notification to inform the user that server has sent a message.
*/
#SuppressWarnings("deprecation")
private static void generateNotification(Context context, String message) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
//message = "vivek";
// Log.d("anjan", message.split("~")[0]);
//Toast.makeText(context, message, Toast.LENGTH_LONG).show();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
String title = context.getString(R.string.app_name);
Log.d("anjan1", title);
String text_message = context.getString(R.string.title_activity_main);
Log.d("anjan1", text_message);
Intent notificationIntent = new Intent(context, Splash.class);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
Try this instead of the last line :
mNotificationManager.notify(0, mBuilder.getNotification());
How can one differentiate the Notifications and pass them to different activities?
In the below method the third parameter(String tag) value is retreived from onMessage() that contains a value.
According to that value i wanted to differentiate which URL to open e.g Google or Facebook.
The app terminates after i include the intent code in the "if" conditions below.
Please Help
private static void generateNotification(Context context, String message,
String tag) {
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.ic_launcher,
message, when);
String title = context.getString(R.string.app_name);
Log.d("GCM", "Tag Value " + tag);
if (tag.equals("one")) {
// pass to a different activity
notificationIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse("https://www.google.com"));
}
if (tag.equals("two")) {
// pass to a different activity
notificationIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse("https://www.facebook.com"));
}
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
}
On Manifest create intent filter for activities,that you need launch like this
<activity
android:name=".activities.TabsActivity"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="com.dittoadvertising.push" >
</action>
<category android:name="android.intent.category.DEFAULT" >
</category>
</intent-filter>
when
Uri.parse("https://www.facebook.com") = action name in filter
and in your activities will be called method onNewIntent(Intent newIntent), then intent incoming
Change your code to something like :
if (tag.equals("one")) {
notificationIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse("https://www.google.com"));
} else if (tag.equals("two")) {
notificationIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse("https://www.facebook.com"));
}