how to display notififcations one by one? - android

he, i am new to android platform.
Now i am developing a small application based on notifications.
In my application i am maintaining a timer based on that time every time a notification is displayed.
But the problem is first time notification is displayed and the second notification is appended above the first notification , third notification is append above the second notification..................
I want to display the notifications one by one.
if any one has idea how to display the notification one by one .please reply me.
here is my code
myTimer = new Timer();
myTimer.schedule(new TimerTask()
{
#Override
public void run()
{
TimerMethod();
}
}, 10000,10000);
}
private void TimerMethod()
{
this.runOnUiThread(Timer_Tick);
}
private Runnable Timer_Tick = new Runnable()
{
public void run()
{
mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
final Notification notifyDetails = new Notification(R.drawable.icon,"New Alert, Click Me!",System.currentTimeMillis());
Context context = getApplicationContext();
CharSequence contentTitle = "Notification Details...";
CharSequence contentText = "you have a new notification find clicking me";
Intent notifyIntent = new Intent(Notifi.this,Notifi.class);
PendingIntent intent =
PendingIntent.getActivity(Notifi.this, 0,
notifyIntent, android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
notifyDetails.setLatestEventInfo(context, contentTitle, contentText, intent);
mNotificationManager.notify(SIMPLE_NOTFICATION_ID, notifyDetails);
}
};
Thanks in advance

Store a fixed amount of time say 5000ms in a variable.
Now, start the 1st notification and get the current system time. To this add that 5000ms and continue processing. At the end of 5000ms close the notification. If the 2nd notification must be displayed within 5secs of the 1st one, then use a if condition statement and check whether 5000ms have elapsed since the start time of 1st notification. If it has elapsed then display the 2nd one, else wait till the 1st one completes.
You can also simply check if any notification is open using a simple flag that will be set to 1 when a notification starts and to 0 when it closes. If it is 0, a new notification can be displayed.
[You may also be able to use 2 threads to do this. On 1st thread run all processes. The 2nd one just interrupts the 1st one at set periods after being started. But haven't tried out this]
Hope I was able to help you.

Related

How can I show a different notification each time which open different activity?

I am trying to build an affirmation app which shows notification as an affirmation text and when user clicks on the notification it should take it to an activity, So far i am able to display notifications on hourly basis but i have no idea how to display different notifications each hour which opens a different activity each time because there is gonna be a random list of affirmations which will be displayed as notifications.
EDIT:
My MainActivity:
private void hourly()
{
Calendar calender=Calendar.getInstance();
Intent intent=new Intent(getApplicationContext(),notification_receiver.class);
PendingIntent pendingintent=PendingIntent.getBroadcast(this,100,intent,PendingIntent.FLAG_UPDATE_CURRENT);
// calender.setTimeInMillis(System.currentTimeMillis());
//// calender.set(Calendar.HOUR_OF_DAY, 10);
//// calender.set(Calendar.MINUTE, 30);
alarmmanager=(AlarmManager)getSystemService(ALARM_SERVICE);
int interval=60000;
alarmmanager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
interval,
interval, pendingintent);
Toast.makeText(this, "Success", Toast.LENGTH_SHORT).show();
}
My notification_receiver class:
public class notification_receiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
ArrayList<String> notificationTexts = null;
notificationTexts.add("This is a nice day"); // this will go to notificationTexts in position 0;
notificationTexts.add("This is nice morning");
Random rand = new Random();
int n = rand.nextInt(notificationTexts.size());
NotificationManager notificationManager= (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent repeating_activity=new Intent(context,repeating_activity.class);
repeating_activity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent=PendingIntent.getActivity(context,100,repeating_activity,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder=new NotificationCompat.Builder(context)
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.common_google_signin_btn_icon_dark)
.setContentTitle("Affirmation")
.setContentText(notificationTexts.get(n))
.setAutoCancel(true);
notificationManager.notify(100,builder.build());
}
}
You already have a mechanism to show the notifications so what you are needing is a sort of backend where you can select a random text linked to a certain activity of your app.
In your main activity you can have 2 lists:
private ArrayList<Srtring> notificationTexts;
private ArrayList<Class> activitiesToStart;
Whith these two you add the text for your affirmations and the activity class you want to start under the same index of position in the list.
For example:
notificationTexts.add("This is a nice day"); // this will go to notificationTexts in position 0;
activitiesToStart.add(TheNiceDayActivity.class); //this will go to the activitiesToStart also in position 0;
In the mechanism you already have working, when you prepare the notification, you just have to calculate a random number between 0 and the length of either Lists, and pick the text from the first list and the activity from the second one. To pick the corresponding element you do it with list.get(position);
Once you got the activity, you create the PendingIntent that goes in the notification setup at the time of building it.
I haven't tried it but it should give you an idea on how it can be done.
EDIT I
A random number between 0 and 19 (including the 19) can be calculated with:
Random rand = new Random();
int n = rand.nextInt(20);

How to prevent notification from opening an activity or removed when clicked in Android?

I am developing an Android app. I my app, I am trying to show process notification to user. But what I want is I do not want notification opening an Activity or removed when it is get clicked. What I am doing is I am showing notification when a user click a button. Notification will saying "Transferring data". Notification is fired from receiver.
So when user click a button, receiver is called. But I do not want that notification removed or closed when user click it. I do not want to show any activity as well. I just want to close itself when data processing finish.
This is my receiver that show notification when button is clicked
public class GalleryImageUploadReceiver extends BroadcastReceiver {
private Context context;
private NotificationCompat.Builder notification;
#Override
public void onReceive(Context pContext, Intent intent) {
this.context = pContext;
showProcessNotification();
doAsyncTaskInBackground()
}
public void doAsyncTaskInBackground()
{
//I want to close it here after task is finished
}
public void showProcessNotification()
{
try{
notification = new NotificationCompat.Builder(context);
notification.setAutoCancel(true);
notification.setSmallIcon(R.mipmap.ic_launcher);
notification.setWhen(System.currentTimeMillis());
notification.setTicker("Transferring data...");
notification.setContentTitle(context.getResources().getString(R.string.app_name));
notification.setContentTitle("Transferring data...");
notification.setOngoing(true);
notification.setDefaults(Notification.FLAG_ONGOING_EVENT);
Intent i = new Intent(context.getApplicationContext(), MainActivity.class);//In this line, I do not want to open any activity
i.putExtra("start", OfficeMainActivity.FRAGMENT_NOTIFICATIONS);
PendingIntent pendingIntent = PendingIntent.getActivity(context.getApplicationContext(),0,i,PendingIntent.FLAG_UPDATE_CURRENT);
notification.setContentIntent(pendingIntent);
NotificationManager nm = (NotificationManager)context.getApplicationContext().getSystemService(context.getApplicationContext().NOTIFICATION_SERVICE);
nm.notify(1,notification.build());
}
catch (Exception e)
{
}
}
public void uploadImages(Context context,Intent intent)
{
onReceive(context,intent);
}
}
Receiver is called in button click event like this
GalleryImageUploadReceiver receiver = new GalleryImageUploadReceiver();
receiver.uploadImages(getBaseContext(),new Intent());
As you can see, I set ongoing to true because I want to make it undismissable. But the problem is it is closed because an activity is opened.
These are what I want:
I do not want to open an activity when notification is clicked.
I only want it close itself. How can I do that?
Instead can show option dialog with buttons?
But I do not want that notification removed or closed when user click it.
remove this
notification.setAutoCancel(true);
I do not want to open an activity when notification is clicked.
remove this
Intent i = new Intent(context.getApplicationContext(), MainActivity.class);//In this line, I do not want to open any activity
i.putExtra("start", OfficeMainActivity.FRAGMENT_NOTIFICATIONS);
PendingIntent pendingIntent = PendingIntent.getActivity(context.getApplicationContext(),0,i,PendingIntent.FLAG_UPDATE_CURRENT);
notification.setContentIntent(pendingIntent);
I suggest you read up on notification documentation. This is pretty straightforward stuff.
How can I close if self please?
you can "close" a notification manually with
nm.cancel(1); // if 1 is your notification id.
Instead can show option dialog with buttons?
Instead of doing that you should just present the buttons inside the notification.

Should I create 5 different receivers/services for my app?

I just started making an application aside from school and work and am not sure what route I should take. Essentially, I am building an app that calculates 5 different prayer times that change every day (the 5 prayers are named Fajr, Zuhr, Asr, Maghrib, and Isha). The calculation is done locally on the device and I found open source code for that and got it to calculate them properly. Once the getTimes() method is called, the prayer times should be calculated for that day and then recalculated once every single day after that. I'm thinking the setRepeating() method of the AlarmManager class would be good for that. How would I go about that? Once the prayer times are calculated, a service(s) should be started to create a notification at that exact time to notify the user that it is time to pray. The dilemma here is that I don't think that I should be using 5 different services/receivers to notify for each of the 5 different prayers. What would be the best way to go about this?
Currently, my app only notifies the user of Maghrib (one of the prayers) prayer time. It does not recalculate the times either.
Sorry if I am not very clear as I am new to this. I can expand more if needed.
My getTimes() method: (for the sake of simplicity I have removed the code that calculates the times)
public void getLocationTime(View v) {
//Maghrib
Calendar calMaghribTime = Calendar.getInstance();
calMaghribTime.set(Calendar.HOUR_OF_DAY, getHourOfDay(strMaghribTime));
calMaghribTime.set(Calendar.MINUTE, Integer.parseInt(strMaghribTime.substring(3,5)));
calMaghribTime.set(Calendar.SECOND, 0);
Intent myIntent = new Intent(MainActivity.this, NotificationCreatorReceiver.class);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, calMaghribTime.getTimeInMillis(), pendingIntent);
Toast.makeText(this, "NotificationCreator onReceive()", Toast.LENGTH_SHORT).show();
} //end of getLocationTime()
Here is my receiver:
public class NotificationCreatorReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service1 = new Intent(context, NotificationCreatorService.class);
context.startService(service1);
}
}
Here is my service:
public class NotificationCreatorService extends Service {
#Override
public IBinder onBind(Intent arg0)
{
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate()
{
super.onCreate();
// TODO Auto-generated method stub
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "NotificationCreator onStartCommand()", Toast.LENGTH_SHORT).show();
// Use NotificationCompat.Builder to set up our notification.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
//icon appears in device notification bar and right hand corner of notification
builder.setSmallIcon(R.mipmap.ic_launcher);
// This intent is fired when notification is clicked
Intent intent1 = new Intent(this.getApplicationContext(),MainActivity.class);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(this.getApplicationContext(),
0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
// Set the intent that will fire when the user taps the notification.
builder.setContentIntent(pendingNotificationIntent);
// Content title, which appears in large type at the top of the notification
builder.setContentTitle("It's time for Maghrib");
// Content text, which appears in smaller text below the title
builder.setContentText("Maghrib prayer time has started in your area");
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Will display the notification in the notification bar
notificationManager.notify(0, builder.build());
return START_STICKY;
}
#Override
public void onDestroy()
{
// TODO Auto-generated method stub
super.onDestroy();
}
}
The short answer - probably 1 service, 5 receivers. A Receiver is designed to listen for events and take quick action. A Service should be used to do all of the "heavy lifting" if necessary.
A Receiver should listen for an event and, if you only need to post a notification, then you can probably just do that and be done. But if you want to do much of anything else, it should pass an Intent to the Service with data to tell the Service how to respond.
EDIT:
Receivers have 10 seconds to do their job or else an ANR (Application Not Responding) error will occur. (See the docs: http://developer.android.com/reference/android/content/BroadcastReceiver.html) Creating and sending a notification should not take this long.
However, "good design" means you should acquire a Wake Lock and then pass an intent to a Service to do much of anything. Also, you will probably find that you will want to do "other processing" at some point. However, if I were you and all that is required is to post a notification, I'd just use the Receiver and worry about it later. I've probably processed over a billion notifications this way without error. But a code reviewer may argue that it's "possible" for an ANR to occur... blah... blah... blah...

Android Wear custom Notification

When the custom notification is peeking on the homescreen, the system displays it with a standard template that it generates from the notification's semantic data. I have to swipe the notification up, to see the custom activity for the notification. I'm showing 'Swipe up to view' text as title for standard template. My question is, Can i replace "Swipe up to view" with a time counter, which increase with timer?
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String ns = getApplicationContext().NOTIFICATION_SERVICE;
mNotificationManager = (NotificationManager) getSystemService(ns);
callNotification(Html.fromHtml(getFormattedTime(CurrentPausedTime)),false,false);
Thread notifyingThread = new Thread(null, updateTimerTaskCustom, "NotifyingServiceNew");
notifyingThread.start();
}
private void callNotification(final Spanned spanned,boolean isPause,boolean pauseAction) {
// TODO Auto-generated method stub
displayIntent = new Intent(getApplicationContext(), CustomNotification.class);
displayIntent.putExtra("exerciseTitle", "Running");
displayIntent.putExtra("duration", CurrentPausedTime);
displayIntent.putExtra("elepsedTime", 0);
displayIntent.putExtra("isPause", isPause);
displayPendingIntent = PendingIntent.getActivity(getApplicationContext(),
0, displayIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent deleteIntent = new Intent(getApplicationContext(), ClearNotification.class);
deletePendingIntent = PendingIntent.getActivity(getApplicationContext(),
0, deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent pauseIntent = new Intent(ExerciseActionReciever.ACTION_PAUSE,
null,getApplicationContext(), ExerciseActionReciever.class);
pausePendingIntent = PendingIntent.getBroadcast(getApplicationContext(),
0, pauseIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent stopIntent =new Intent(ExerciseActionReciever.ACTION_STOP,
null,getApplicationContext(), ExerciseActionReciever.class);
stopPendingIntent = PendingIntent.getBroadcast(getApplicationContext(),
0, stopIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent resumeIntent = new Intent(ExerciseActionReciever.ACTION_RESUME,
null, getApplicationContext(), ExerciseActionReciever.class);
resumePendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, resumeIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.WearableExtender wearableExtender =
new NotificationCompat.WearableExtender()
.setHintHideIcon(true)
.setContentIcon(R.drawable.icon)
.setDisplayIntent(displayPendingIntent);
mNotifyBuilder =
new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.icon)
.setContentTitle(""+spanned)
.setDeleteIntent(deletePendingIntent)
.extend(wearableExtender)
.addAction(R.drawable.icon, "Resume", resumePendingIntent)
.addAction(R.drawable.icon, "Stop", stopPendingIntent);
}
private Runnable updateTimerTaskCustom = new Runnable() {
public void run() {
timerHandlerCustom.removeCallbacks(updateTimerTaskCustom);
timerHandlerCustom.postDelayed(updateTimerTaskCustom, 1000);
if(!CustomNotification.isCustomCardAcrivityvisible )
{
CurrentPausedTime = CurrentPausedTime+1000;
mNotifyBuilder.setContentTitle(""+Html.fromHtml(getFormattedTime(CurrentPausedTime)));
mNotificationManager.notify(NOTIFICTIONTION_ID , mNotifyBuilder.build());
}
}
};
You can replace "Swipe up to view" with any text you want - like "53 sec". To update this value you will need to simply update your notification.
More information about updating notifications: http://developer.android.com/training/notify-user/managing.html
BTW. If you want to optimise your code the note on top might be important to you:
When you need to issue a notification multiple times for the same type
of event, you should avoid making a completely new notification.
Instead, you should consider updating a previous notification, either
by changing some of its values or by adding to it, or both.
EDIT: If you want, in addition, to use this solution with custom layout Activity you need to prevent notification from refreshing when this Activity is visible. Otherwise you will end up with Activity being created over and over again (blinking layout). Custom Activity in card layout is visible between the onResume and onPause events, so you need to detect that and update the whole notification ONLY when Activity is NOT visible to the user. The simpliest way is to use a static flag, but you can also play with other more advanced solutions (like LocalBroadcastManager etc.) to achieve this goal.
public class CustomLayoutActivity extends Activity {
public static boolean isCustomCardAcrivityvisible;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom_layout_activity);
}
#Override
protected void onResume() {
super.onResume();
isCustomCardAcrivityvisible = true;
}
#Override
protected void onPause() {
super.onPause();
isCustomCardAcrivityvisible = false;
}
}
and if you're about to refresh your notification just do following check:
if(!CustomLayoutActivity.isCustomCardAcrivityvisible) {
updateNotification();
}
Alternatively you can use setUsesChronometer(boolean b) method, to just display a timer (instead of contextText) that will be refreshed for you, but please notice that the timer will only be displayed (on Android Wear) if you will NOT set a custom layout to your card. So while this is not exactly what you want, you may consider this instead.
Show the when field as a stopwatch. Instead of presenting when as a
timestamp, the notification will show an automatically updating
display of the minutes and seconds since when. Useful when showing an
elapsed time (like an ongoing phone call).

Techniques to implement a notification service

I have a main activity where the user can enable/disable notifications, set the notification interval, and set the base time the notification interval will use. Notifications will typically trigger about 2 hours from each other. After a certain time, an accumulator will reach a maximum value and notifications will no longer be needed.
What is the standard way of implementing such a notification scheme? I tried using a handler inside of a service using postAtTime, but it seems that there are a lot of conditions that can cause it to never run. I looked at a timer inside of the service, but putting the phone in standby will stop any timers, plus it just seems like a bad idea.
The only other option I came across I have yet to explore, but it involves using an AlarmManager and a BroadcastReceiver. Should I just ditch the service and schedule a repeating alarm instead? I need to be able to disable all remaining alarms once my accumulator has reached max value.
Thanks for any input.
What if you start a service that spawns a thread like this:
thread t = new thread(new Runnable(){
public void Run(){
boolean notified = false;
while( !notified ){
if( notify_time - time > 1000 ){
Thread.sleep(999);
else if( notify_time - time <= 0 ){
// START NOTIFICATION ACTIVITY
notified = true;
}
}
}
}
t.start();
I have not done anything like this personally, so I am not sure what service can do to notify the user or start an activity, but it does have the full panoply of options available to an activity, so yeah.
Oh but it just occured to me you'll need to use a handler for that because of the multithreaded aspect here.
Since I will always have a finite number of notifications and I can calculate the elapsed time in advance, it seems the combination of AlarmManager and a BroadcastReceiver work pretty well. Here is how I implemented this:
I first created a BroadcastReceiver
public class NotificationReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//Get handle to system notification manager
NotificationManager mNM = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
//Get message from intent
Bundle bundle = intent.getExtras();
CharSequence text = bundle.getString("notification_message");
// Set the icon, scrolling text and timestamp
Notification notification = new Notification(R.drawable.notification_icon, text, System.currentTimeMillis());
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(context, context.getText(R.string.app_name),text, contentIntent);
// Set Flags
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Send the notification.
mNM.notify(R.string.notification, notification);
}
}
I then created a class that used a AlarmManager to create/cancel alarms that send a message to the BroadcastReceiver
public class NotificationSender {
private AlarmManager mAlarmManager;
private Context mContext;
private Intent mIntent;
public NotificationSender(Context context){
this.mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
this.mIntent = new Intent(context, NotificationReceiver.class);
this.mContext = context;
}
public void setAlarm(Long etaMillis, int accumulator){
//Create intent to send to Receiver
this.mIntent.putExtra("notification_message","Message");
//Use accumulator as requestCode so we can cancel later
PendingIntent sender = PendingIntent.getBroadcast(this.mContext, accumulator, this.mIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//Set Alarm
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, etaMillis, sender);
}
public void cancelAlarms(){
//requestCode (accumulator) will always be a multiple of 10 and less than 100
for (int x = 10; x <= 100; x += 10){
PendingIntent operation = PendingIntent.getBroadcast(this.mContext, x, this.mIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mAlarmManager.cancel(operation);
}
}
public void createAlarms(PreferenceHelper prefs){
//Calculate time notifications are due and set an alarm for each one
//PreferenceHelper is a class to help pull values from shared preferences
Date currentTime = new Date();
for (int i = prefs.getNotificationInterval(); i <= 100; i += prefs.getNotificationInterval()) {
if (i > prefs.getAccumulator()) {
this.setAlarm(SystemClock.elapsedRealtime() + calculateETA(i, prefs).getTime() - currentTime.getTime(), i);
}
}
}
public void refreshAlarms(PreferenceHelper prefs){
this.cancelAlarms();
if (prefs.isNotificationsEnabled()) this.createAlarms(prefs);
}
}
The important part is to use the accumulator as the requestCode so we can cancel all of our alarms later.
Finally I used the NotificationSender class in my activity by calling refreshAlarms() in onCreate() and whenever the user modifies preferences that are relevant to scheduling notifications. Rebooting the phone will clear all alarms so the app must be restarted before notifications will begin. If the system happens to kills the process, the alarms will still trigger at the appropriate time.

Categories

Resources