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>
Related
I am trying to set up my notification to lead directly to a specific activity. I followed the steps outlined in the official documentation. But clicking the notification only opens the main launcher of the app.
The activity I am trying to launch via the notification is the DetailActivity.
This is how I have set up the activity hierarchy in my manifest.xml
<activity
android:name=".SplashscreenActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".HomeActivity"
android:parentActivityName=".SplashscreenActivity"/>
<activity
android:name=".DetailActivity"
android:parentActivityName=".HomeActivity"/>
In my onMessageReceived method of the FirebaseMessagingService class, I have the following:
Intent resultIntent = new Intent(this, DetailActivity.class);
// Create the TaskStackBuilder and add the intent, which inflates the back stack
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntentWithParentStack(resultIntent);
// Get the PendingIntent containing the entire back stack
PendingIntent intent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mNotificationManager.notify(
NOTIFICATION_ID,
getNotification("title", "text", intent)
);
The getNotification method:
private Notification getNotification(String title, String text, PendingIntent intent) {
return new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(text)
.setContentIntent(intent)
.setOngoing(true)
.build();
}
I don't know if this issue is that the activity I am trying to launch is not the direct child of the launcher activity. And I am not sure how to debug this either. Hoping someone has run into this weird issue before!
use this:
Intent notificationIntent = new Intent(this, DetailActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent. FLAG_ONE_SHOT);
and use this pendingIntent in Notification.
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this,"x")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("your title")
.setAutoCancel(true)
.setSound(soundUri)
.setContentIntent(pendingIntent)
.setPriority(Notification.PRIORITY_HIGH);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
notification code
How do I start an activity over the lock screen after clicking on a notification? Whatever I do it asks for my password and starts the activity after I unlock. It doesn't even get to the onCreate methods.
<activity
android:name=".Locktask"
android:configChanges="orientation"
android:excludeFromRecents="true"
android:noHistory="true"
android:showOnLockScreen="true"
android:showWhenLocked="true"
android:taskAffinity=""
android:exported="true"
android:screenOrientation="portrait"
android:launchMode="singleTask"
android:theme="#style/AppTheme.NoActionBar" />
Intent intent = new Intent(this, Locktask.class);
PendingIntent pi = PendingIntent.getActivity(this, 2, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("locknote",
"locknote name",
NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("shows layout over lock.");
channel.enableLights(true);
channel.setLightColor(Color.RED);
channel.enableVibration(true);
channel.setShowBadge(false);
channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
channel.setVibrationPattern(new long[] { 0,0 });
channel.enableVibration(false);
if (mNotificationManager != null) {
mNotificationManager.createNotificationChannel(channel);
}
}
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, "locknote")
.setContentTitle("w")
.setContentText("e")
.setContentIntent(pi)
.setSmallIcon(R.drawable.ic_action_lock_notification)
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(2, mBuilder.build());
Not a duplicate as that answer's permissions have already been added.
Edit: SOVLED
For any poor souls in the future, the notification has to have a custom layout with setCustomContentView() and a onclickpendingintent set to that view. The pending intent should point to an intent service, it's the only way intents can get handled from notifications while still locked.
Try this:
Intent intent = new Intent(this, Locktask.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pi = PendingIntent.getActivity(this, 2, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Basically, I'm browsing the internet in chrome or looking at another app. I get a notification that opens my application. I do some stuff and it finishes. My application closes and i'm back on the launcher. How can I get my app to finish and return me to whatever previous app/chrome page i was browsing?
AndroidManifest section for this activity:
<activity
android:name=".AcceptRejectActivity"
android:label="#string/title_activity_accept_reject"
android:screenOrientation="portrait" >
</activity>
Notification code:
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
Intent resultIntent = new Intent(this, AcceptRejectActivity.class);
resultIntent.putExtra("message","Do you choose to accept this message?");
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(AcceptRejectActivity.class);
// Adds the Intent that starts the Activity to the top of the stack //
stackBuilder.addNextIntent(resultIntent);
PendingIntent contentIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
String msg = "You have a message"
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_logo)
.setContentTitle("Message")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg)
.setPriority(Notification.PRIORITY_HIGH);
mBuilder.setContentIntent(contentIntent);
mBuilder.setAutoCancel(true);
android.app.Notification note = mBuilder.build();
note.defaults |= android.app.Notification.DEFAULT_VIBRATE;
note.defaults |= android.app.Notification.DEFAULT_SOUND;
mNotificationManager.notify(0, note);
Fragment's close function
private void allDone() {
Log.i(TAG, "The choice has been made");
getActivity().finish();
//NavUtils.navigateUpFromSameTask(getActivity());
}
Well that´s a little bit weird, but like an option you can open the browser after the finish your application.
private void allDone() {
Log.i(TAG, "The choice has been made");
getActivity().finish(); //finish your app!.
//NavUtils.navigateUpFromSameTask(getActivity());
try { //Open browser!.
Uri uri = Uri.parse("googlechrome://navigate?url=");
Intent i = new Intent(Intent.ACTION_VIEW, uri);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
} catch (ActivityNotFoundException e) {
// Chrome is not installed
}
}
Then you will return to your Chrome session ;).
I managed to solve my issue.
Android Manifest:
<activity
android:name=".AcceptRejectActivity"
android:label="#string/title_activity_accept_reject"
android:screenOrientation="portrait"
android:launchMode="singleInstance"
android:excludeFromRecents="true">
</activity>
Notification code:
Changed how the pendingIntent was created.
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
Intent resultIntent = new Intent(this, AcceptRejectActivity.class);
resultIntent.putExtra("message","Do you choose to accept this message?");
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
String msg = "You have a message"
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_logo)
.setContentTitle("Message")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg)
.setPriority(Notification.PRIORITY_HIGH);
mBuilder.setContentIntent(contentIntent);
mBuilder.setAutoCancel(true);
android.app.Notification note = mBuilder.build();
note.defaults |= android.app.Notification.DEFAULT_VIBRATE;
note.defaults |= android.app.Notification.DEFAULT_SOUND;
mNotificationManager.notify(0, note);
Now when I'm done my processing I can just call finish() or getActivity().finish() and it will take me back to whatever app/browser page you were on before clicking the notification.
I'm making a gcm application, and now I can receive the notification
But when I click the notification, it just open the app.
I need to open another activity instead of Mainactivity
is there any way to do this?
final Intent intent = new Intent(context, YourActivity.class);
intent.putExtra("key", "value");
final PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
final NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.set...;
final NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, builder.build());
Please read this for detail about creating a Notification http://developer.android.com/guide/topics/ui/notifiers/notifications.html.
Depend on http://developer.android.com/guide/topics/ui/notifiers/notifications.html#NotificationResponse, there are two general situations of starting Activity from your notification – Regular activity and Special activity.
Methods below are the example of start 2 type of Activity:
Regular activity
private static final int NOTIFICATION_ID = 602;
private static final int REQUEST_CODE_START_ACTIVITY = 610;
/**
* Create and show a simple notification containing the received GCM message.
*/
private void sendNotification(String title, String message, Intent intent) {
// Create a start PendingIntent
PendingIntent resultPendingIntent = null;
ComponentName componentName = intent.getComponent();
if (componentName != null) {
// 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) <== This comment must be wrong!
stackBuilder.addParentStack(componentName);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(intent);
resultPendingIntent = stackBuilder.getPendingIntent(REQUEST_CODE_START_ACTIVITY, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT);
} else {
resultPendingIntent = PendingIntent.getActivity(this, REQUEST_CODE_START_ACTIVITY, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT);
}
// Notification properties
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_ic_notification)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setContentIntent(resultPendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build());
}
Usage :
Intent intent = new Intent(this, SignInActivity_.class);
sendNotification(TextUtils.isEmpty(title) ? getString(R.string.app_name) : title, message, intent);
The manifest XML should look like this
<activity
android:name=".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=".SignInActivity_"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/>
</activity>
Special activity
private static final int NOTIFICATION_ID = 602;
private static final int REQUEST_CODE_START_ACTIVITY = 610;
/**
* Create and show a simple notification containing the received GCM message.
*/
private void sendNotification(String title, String message, Intent intent) {
// Create a start PendingIntent
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, REQUEST_CODE_START_ACTIVITY, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT);
// Notification properties
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_ic_notification)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setContentIntent(resultPendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build());
}
Note:
Because I use setDefaults(DEFAULT_ALL), the vibrate permission is require <uses-permission android:name="android.permission.VIBRATE" />
Yes, it's possible. You must set the "exported" flag of the activity in the manifest.xml to true.
Hope it helps.
Use this:
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager nm=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent=new Intent(context,YourActivity.class);
PendingIntent pending=PendingIntent.getActivity(context, 0, intent, 0);
Notification notification;
if (Build.VERSION.SDK_INT < 11) {
notification = new Notification(icon, "Title", when);
notification.setLatestEventInfo(
context,
"Title",
"Text",
pending);
} else {
notification = new Notification.Builder(context)
.setContentTitle("Title")
.setContentText(
"Text").setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pending).setWhen(when).setAutoCancel(true)
.build();
}
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults |= Notification.DEFAULT_SOUND;
nm.notify(0, notification);
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());