In my application, I have two main activities:
MainActivity and MessagesActivity
When the notification is clicked and the application is not running, I want it to start the MainActivity. However, when the application is running and the MessagesActivity is in view, I want when the user clicks the notification to somehow receive the intent data.
I create my notification something like this:
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.putExtra(MESSAGE_KEY, receivedMessage);
notificationIntent.putExtra(MESSAGE_ID_KEY, receivedMessageId);
int requestID = (int) System.currentTimeMillis();
PendingIntent contentIntent = PendingIntent.getActivity(context, requestID, notificationIntent, PendingIntent.FLAG_ONE_SHOT, intent.getExtras());
Notification notification = new Notification.Builder(context)
....build();
notificationManager.notify(requestID, notification);
I've tried playing around with other flags, launchModes, etc. This wouldn't be a problem if it was all just one activity but onNewIntent is never called when the application is running in either MainActivity or MessagesActivity
Related
I am trying to display a notification about incoming call (from within my app) to a user. I found out that I can use NotificationCompat.Builder.setFullScreenIntent() to make a notification persistent on the top of the screen when application is running in the background.
However now when user does not answer the call and other party stops ringing how do I make that full screen intent disappear and show it inside a notification bar?
The only way I can think of is calling cancel() on that notification ID and creating a new one without full screen intent. But is this a good way of doing this? Is there a 'good practice' on how to achieve what I want?
Snippet showing how I create the notification:
public void displayNotification(String title, String text, int conversationId) {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
this.createNotificationChannel();
Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this.context, 0, intent, PendingIntent.FLAG_IMMUTABLE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this.context, this.channelID);
builder.setContentTitle(title);
builder.setContentText(text);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setFullScreenIntent(pendingIntent, true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this.context);
notificationManager.notify(conversationId, builder.build());
}
I have an app that sends notifications, and when clicked, opens an activity from my app. If you launch the app and keep the app open and click notifications, it works properly. However, when the app is closed, it doesn't. This is what happens:
Close app > receive notification > click notification > opens the correct activity > receive another notification > nothing happens when clicked
The intended functionality is for the notification to open the activity regardless if it is already open, and just add it onto the task stack. So if you clicked 3 notifications, the stack would be ActivityA > ActivityA > ActivityA. Here is the code for the notification:
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
notificationManager.notify(ID, new NotificationCompat.Builder(context, CHANNEL_ID)
.setOnlyAlertOnce(false)
.setAutoCancel(true)
.setCustomContentView(helper.createSmallView(context))
.setCustomBigContentView(helper.createBigView(context))
.setContentIntent(PendingIntent.getActivity(context, 1,
new Intent(context, ActivityA.class),
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE)
)
.build());
I also tried using a broadcast PendingIntent. The BroadcastReceiver would be called but the call to Context#startActivity did nothing.
Intent intent = new Intent(YourActivity.class, NewActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE);
PendingIntent
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
notificationManager.notify(ID, new NotificationCompat.Builder(context, CHANNEL_ID)
.setOnlyAlertOnce(false)
.setAutoCancel(true)
.setCustomContentView(helper.createSmallView(context))
.setCustomBigContentView(helper.createBigView(context))
.setContentIntent(pendingIntent)
.build());
I have sync adapter that performs some operation in background. To notify my main activity about sync operation status, I used broadcast receivers, so my activity is able to receive messages from sync adapter. It works fine. However, I also need to display notification on android status bar, that indicates some sync results.
So I wrote simple method reponsible to disaply system notification:
private void sendNotification(Context ctx, String message)
{
Intent intent = new Intent(ctx, this.getClass());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(ctx)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Mobile Shopping")
.setContentText(message)
.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_SOUND | Notification.FLAG_SHOW_LIGHTS)
.setLights(0xff00ff00, 300, 100)
.setPriority(Notification.PRIORITY_DEFAULT);
//.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 , notificationBuilder.build());
}
Then, above method is called in onPerform sync:
#Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult)
{
.................
sendNotification(context, message);
}
Context is retrieved from constructor. It works without any problems, notification is showing.
However I also need to show main activity after user cicks on notification. So I believe I need to create PendingIntent and pass it to my notification builder (as it's commented in my code). But to pass main activity object to my sync adapter? Notification can be also displayed after auto sync finished.
Any tips?
So, I figured it out. Solution is to create pending intent this way:
Intent notificationIntent = new Intent(ctx, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(ctx, 0, notificationIntent, 0);
So after user clicks to notification, main activity will be shown.
I wrote an app and I set an alarm manager which set to send a notification every 3 hours. Assume my notification has to be send at 11:10 and my phone is getting off at 11:00. So, I will not receive any notification. When my phone is turned on, I will receive the next notification at 2:10, so everything is working correctly.
Although, it was observed that I will not receive any notification after my phone is getting off for two round of notification. Do you have any suggestion?
The code is provided:
Intent intentAlarm = new Intent(this, NotifyBroadcast.class);
PendingIntent pintentAlarm = PendingIntent.getBroadcast(this, 0, intentAlarm, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
// Start every 30 seconds
mgr.setRepeating(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis(), 300, pintentAlarm);
// NotifyBroadcast:
public class NotifyBroadcast extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent resultIntent = new Intent(context, MainActivity.class);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
context,
0,
resultIntent,
0
);
Notification notification = new Notification(R.drawable.ic_launcher, "Let me know what is your emotion buddy!", System.currentTimeMillis());
notification.defaults |= Notification.DEFAULT_SOUND;
notification.sound = Uri.parse("file:///sdcard/notification/notification.mp3");
//notification.flags = Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(context, "emotion interface", "Let me know what is your emotion buddy!", resultPendingIntent);
int mId = 001;
// mId allows you to update the notification later on.
mNotificationManager.notify(mId, notification);
// mNotificationManager.notify(mId,mBuilder.build());
// mNotificationManager.cancel(mId);
}
}
I didn't understand following part very well :
I will not receive any notification after my phone is getting off for two round of notification .
Just check that you are relaunching your service after reboot. For that you need to add a receiver that launches your Service again after the reboot. You need to handle that on android.intent.action.BOOT_COMPLETED intent broadcast. Some of the questions that might help you are:
Android: make notification persist across phone reboot
android notification after reboot
Android: why did the Alarm notification stop after system reboot
Hope this helps in some way.
I'm working on my first Android app to use the Google Cloud Messaging (GCM) service for push notifications. I've got to the point where I can successfully send a message from my server application, and log the content of the message in the onMessage event within my GCMIntentService class on the client app. However I don't see any visual indication on the device that a message was received. I was expecting the message to appear in the pull-down notifications list on the phone, as it does on the iPhone. Does this have to be coded manually? Also is there a common method for displaying the message regardless of which activity is currently active, and if the app is idle in the background? Any help appreciated.
This code will generate a notification in the android system bar at the top of the screen. This code will create a new intent that will direct the user to a "Home.class" after clicking on the notification in the top bar. If you would like it to do something specific based on the current activity you could send broadcast requests from the GCMIntentService to your other activities.
Intent notificationIntent=new Intent(context, Home.class);
generateNotification(context, message, notificationIntent);
private static void generateNotification(Context context, String message, Intent notificationIntent) {
int icon = R.drawable.icon;
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);
// 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, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
}
Note that this example uses resources in R.drawable and R.String that will need to be present to work but it should give you the idea. See this for more information about status notifications http://developer.android.com/guide/topics/ui/notifiers/index.html and this about broadcast recievers. http://developer.android.com/reference/android/content/BroadcastReceiver.html
If you are using GcmListenerService you can use this code, add to your onMessageReceived the sendNotification()
#Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
sendNotification(message);
}
private void sendNotification(String message) {
Intent intent = new Intent(this, YOURCLASS.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_park_notification)
.setContentTitle("Ppillo Message")
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}