In my application, i have used C2DM. Here, when i receive a C2DM message/notification, i am trying to create a notification using notification manager. I can properly create notifications, but i am unable to increment the number of unread notifications(using Notification.number) when there are many unread notifications. Since i am creating notification object inside onReceive() function, its getting destroyed as soon as the control comes out of onReceive function. So, the statements
public class MyC2dmReceiver extends BroadcastReceiver{
private Context context;
#Override
public void onReceive(Context context1, Intent intent) {
this.context = context1;
if(intent.getAction().equals("com.google.android.c2dm.intent.REGISTRATION")) {
handleRegistration(context, intent);
}
else if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {
handleMessage(context, intent);
}
}
private void handleMessage(Context context, Intent intent)
{
.....
.....
Notification notification =
new Notification(R.drawable.ic_launcher,intent.getStringExtra("payload"),
System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults = Notification.DEFAULT_ALL;
notification.number += 1;
}
}
have been of no use as it is creating a new notification object everytime. I can not make it(notification object) a static object also. If i make it a static object, even after all the unread notifications are viewed, the notification.number does not get reset. This is basically the problem. Could anybody help me?
Store your number of unread messages in a database, flat file, shared preference, or other persistent store. Read in that number when creating your new Notification.
Related
I am developing an Android app. In my app, I am showing notification that is fired from inside of a broadcast receiver. Showing notification from receiver is working fine. But I am having a little problem with what I want it to be. It is a self-cancel notification. Cannot be closed by user.
What is happening now is when it is fired, it does not append as new notification in notification bar if one is already existing. Just existing one is keep showing. What I want is I want it appended whenever it is fired no matter how many notifications made from that notification manager inside receiver exist.
This is my receiver that fire self-close notification
public class GalleryImageUploadReceiver extends BroadcastReceiver {
private Context context;
private NotificationCompat.Builder notification;
private static final int NOTIFICATION_ID = 1;
private NotificationManager nm;
#Override
public void onReceive(Context pContext, Intent intent) {
this.context = pContext;
initialize(intent);
showProcessNotification();
uploadImagesToServer();
}
private void initialize(Intent intent)
{
//initialize data
}
private void uploadImagesToServer()
{
// do async task and close itself
if(nm!=null)
{
nm.cancel(NOTIFICATION_ID);
}
}
public void showProcessNotification()
{
try{
notification = new NotificationCompat.Builder(context);
notification.setAutoCancel(true);
notification.setSmallIcon(R.mipmap.ic_launcher);
notification.setWhen(System.currentTimeMillis());
notification.setTicker("Uploading image(s)...");
notification.setContentTitle(context.getResources().getString(R.string.app_name));
notification.setContentTitle("Uploading image(s)...");
notification.setAutoCancel(true);
notification.setOngoing(true);
notification.setDefaults(Notification.FLAG_ONGOING_EVENT);
nm = (NotificationManager)context.getApplicationContext().getSystemService(context.getApplicationContext().NOTIFICATION_SERVICE);
nm.notify(NOTIFICATION_ID,notification.build());
}
catch (Exception e)
{
}
}
public void uploadImages(Context context,Intent intent)
{
onReceive(context,intent);
}
}
This is how I am firing notification using receiver in activity
//inside a click listener
GalleryImageUploadReceiver receiver = new GalleryImageUploadReceiver();
receiver.uploadImages(getBaseContext(),intent);
The problem with that code is, when I click button, new notification overrides to the existing one and so only one notification is displayed in the screen. No matter how many times I click it. For example, if notification last 5 seconds, when I click the button again 2 seconds after first one is fired, that existing one will last 7 seconds. New one is not appended in the notification bar. How can I make it to append as new one whenever the button is clicked.
Use a unique notification id for each notification. Because you are using the constant 'NOTIFICATION_ID' new notifications override the existing ones.
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 am trying to display a notification in the Android notifications bar even if my application is closed.
I've tried searching, but I have had no luck finding help.
An example of this is a news application. Even if the phone screen is off or the news application is closed, it can still send a notification for recent news and have it appear in the notification bar.
How might I go about doing this in my own application?
You have to build a Service that handles your news and shows notifications when it knows that are new news (Service Doc).
The service will run in background even if your application is closed.
You need a BroadcastReciever to run the service in background after the boot phase is completed. (Start service after boot).
The service will build your notifications and send them through the NotificationManager.
EDIT: This article may suit your needs
The selected answer is still correct, but only for devices running Android 7 versions and below.
As of Android 8+, you can no longer have a service running in the background while your app is idle/closed.
So, it now depends on how you set up your notifications from your GCM/FCM server. Ensure to set it to the highest priority. If your app is in the background or just not active and you only send notification data, the system process your notification and send it to the Notification tray.
I used this answer to write a service, and as an exmaple you need to call ShowNotificationIntentService.startActionShow(getApplicationContext()) inside one of your activities:
import android.app.IntentService;
import android.content.Intent;
import android.content.Context;
public class ShowNotificationIntentService extends IntentService {
private static final String ACTION_SHOW_NOTIFICATION = "my.app.service.action.show";
private static final String ACTION_HIDE_NOTIFICATION = "my.app.service.action.hide";
public ShowNotificationIntentService() {
super("ShowNotificationIntentService");
}
public static void startActionShow(Context context) {
Intent intent = new Intent(context, ShowNotificationIntentService.class);
intent.setAction(ACTION_SHOW_NOTIFICATION);
context.startService(intent);
}
public static void startActionHide(Context context) {
Intent intent = new Intent(context, ShowNotificationIntentService.class);
intent.setAction(ACTION_HIDE_NOTIFICATION);
context.startService(intent);
}
#Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_SHOW_NOTIFICATION.equals(action)) {
handleActionShow();
} else if (ACTION_HIDE_NOTIFICATION.equals(action)) {
handleActionHide();
}
}
}
private void handleActionShow() {
showStatusBarIcon(ShowNotificationIntentService.this);
}
private void handleActionHide() {
hideStatusBarIcon(ShowNotificationIntentService.this);
}
public static void showStatusBarIcon(Context ctx) {
Context context = ctx;
NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx)
.setContentTitle(ctx.getString(R.string.notification_message))
.setSmallIcon(R.drawable.ic_notification_icon)
.setOngoing(true);
Intent intent = new Intent(context, MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(context, STATUS_ICON_REQUEST_CODE, intent, 0);
builder.setContentIntent(pIntent);
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notif = builder.build();
notif.flags |= Notification.FLAG_ONGOING_EVENT;
mNotificationManager.notify(STATUS_ICON_REQUEST_CODE, notif);
}
}
Scenario:
I have an Alarm scheduled to run on a specified amount of time. Each time is executed, my BroadCastReceiver fires.
In BroadCastReceiver I do all kind of checks and in the end it results a ArrayList of plain Strings
I display an Notification on the Statusbar
When the user taps on a Notification, I display an Activity. I need in my Activity, the ArrayList to display it on views.
Here is the sample code:
public class ReceiverAlarm extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
ArrayList<String> notifications = new ArrayList<String>();
//do the checks, for exemplification I add these values
notifications.add("This is very important");
notifications.add("This is not so important");
notifications.add("This is way too mimportant");
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
//init some values from notificationManager
Intent intentNotif = new Intent(context, NotificationViewer.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intentNotif, 0);
Notification notification = new Notification(icon, text, when);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
notificationManager.notify(NOTIFICATION_ID, notification);
}
And
public class NotificationViewer extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.notification_viewer);
//HERE I NEED the ArrayList<String> notifications
}
I tried most of the things I have found around, from bundles to putStringArrayListExtra() but nothing worked. In my Activity I can't find a way to retrieve the data.
Please help me as I am stuck.
According to the answer marked as the solution HERE if you do not specify an action for your pending intent the extras will not be propagated
As per my suggestion, you may quickly receive it by two ways:
Create your custom class which implements Percelable and design your own implementation to Write and Read parcelable object.
Use Gson to serialize an object into single json string, wrap it inside an intent, receive it at other end and de-serialize the Json string back into your desired object type
there might be some other ways, like Serializing the ArrayList into bytes and write it in a file and read it later, but these two are the best ways I can recommend you to handle any type of information. Personally, I like the second one, using Gson to let it handle everything itself.
Based on all comments the working solution is this:
on BroadCastReceiver
Intent intentNotif = new Intent(context, NotificationViewer.class);
intentNotif.putStringArrayListExtra("list", notifications);
on Activity
Bundle b = getIntent().getExtras();
if (b != null) {
testArrayList= b.getStringArrayList("list");
}
This seems to work just fine.
Im creating an application where I can add appointments to a list.
If an appointment is nearby, I want my app to show a notification in the status bar the day of the appointment at a certain hour.
I used the code from http://developer.android.com/guide/topics/ui/notifiers/notifications.html
to create my notification.
However, the "when" parameter in the script is somewhat confusing because a statusbar notification is always triggered when called.
Notification notification = new Notification(icon, tickerText, when);
What is the best way to schedule such notification?
It seems there is no easy way and I have to create a service that starts a listener Activity with a thread to loop my appointmentdates and show a notification when a date fits the current date?
However, the "when" parameter in the script is somewhat confusing
because a statusbar notification is always triggered when called.
Notification notification = new Notification(icon, tickerText, when);
Exactly - notification is triggered when called. If you set when variable to System.currentTimeMilis() as in the example, it means - show the notification now.
As what triggers your notifications, that is up to you to handle. An Activity doesn't seem like a good choice, but a Service does. Initialize your service on application start (and don't forget to stop it on application exit), and let it do the "listening" and triggering of notifications. It might look as:
public class NotifyService extends Service {
private NotificationManager mNM;
#Override
public void onCreate() {
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
//do some work, listen for change
if (triggerSatisfied) showNotification();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onDestroy() {
// Cancel the persistent notification.
mNM.cancelAll();
}
#Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
private final IBinder mBinder = new LocalBinder();
private void showNotification() {
//code for notification goes here
}
public class LocalBinder extends Binder {
NotifyService getService() {
return NotifyService.this;
}
}