I have create a notification panel but there is some problem .
I have created a service for this but notification is not repeating.
I am not understanding whats problem.
Here is my code:
MainActivity.java
public class MainActivity extends Activity {
Button b1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b1=(Button)findViewById(R.id.button);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent myIntent = new Intent(MainActivity.this , Notification.class);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getService(MainActivity.this, 0, myIntent, 0);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 12);
calendar.set(Calendar.MINUTE, 00);
calendar.set(Calendar.SECOND, 00);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 20*1000 , pendingIntent);
}
});
}
}
Notification.java
public class Notification extends Service{
#Override
public void onCreate() {
Toast.makeText(this, "Notification", Toast.LENGTH_LONG).show();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
#SuppressWarnings("deprecation")
android.app.Notification notification = new android.app.Notification(R.drawable.ic_launcher,"New Message", System.currentTimeMillis());
Intent notificationIntent = new Intent(this,NotificationView.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,notificationIntent, 0);
notification.setLatestEventInfo(this, "hahaha","U have recived new message", pendingIntent);
notificationManager.notify(9999, notification);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
in AndroidManifest.xml I declared permission for alarm and declered service.
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<service android:name=".Notification"></service>
there is a problem, when i click on button then service start an notification show.but notification is not repeating.
You are making the notification using the same id (9999 in your case). So when a new notification is made, all it does is replace the existing notification. So as far you see, only one notification shows up. To see different notifications, you should change the id of your notification in your notify() method.
The other option would be to check if a notification is already displayed (I believe this feature is relatively new) and then update the existing notification to let the user know that a new one has been received.
EDIT:
Besides this, you are only creating the notification once because you only initialize the Notification service once. The next time the alarm manager repeats it sees that the service is already started and does not initialize a new instance. You will have to stop the service before the next scheduled period for the alarm manager to initialize it once again.
This is anyway not advisable. If you need notifications to be scheduled repeatedly, construct notification in a background thread in a service at routine intervals within a loop until a certain condition is met.
Related
I want to display notification every morning at 9 AM from my app.
So I am using Notification Manager, Alarm Manager, BroadcastReciever and Service to make that possible.
But I have a problem, because the notification shows randomly. When I first start the app and set the time, it works OK, but later the app fires and shows notification at random time.
How I can solve that?
Here is my code:
MainActivity
#Override
protected void onStart() {
super.onStart();
setAlarm();
}
public void setAlarm(){
Calendar calendar = Calendar.getInstance();
Calendar now = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 15);
calendar.set(Calendar.MINUTE, 43);
calendar.set(Calendar.SECOND, 0);
if(calendar.getTime().after(now.getTime())) {
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmIntent = new Intent(MainActivity.this, HoroscopeNotification.class);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent); }
}
HoroscopNotification (BroadcastReciever)
public class HoroscopeNotification extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
showNotification(context);
}
private void showNotification(Context context) {
Intent service1 = new Intent(context, AlarmService.class);
context.startService(service1);
}
}
AlarmService
public class AlarmService extends Service {
private static final int NOTIFICATION_ID = 1;
private NotificationManager notificationManager;
private PendingIntent pendingIntent;
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
#SuppressWarnings("static-access")
#Override
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
Context context = this.getApplicationContext();
notificationManager = (NotificationManager)context.getSystemService(context.NOTIFICATION_SERVICE);
Intent mIntent = new Intent(this, MainActivity.class);
pendingIntent = PendingIntent.getActivity(context, 0, mIntent, PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentTitle("Horoskop");
builder.setContentText("Pročitajte današnji horoskop");
builder.setSmallIcon(R.drawable.ic_bik);
builder.setAutoCancel(true);
builder.setContentIntent(pendingIntent);
notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, builder.build());
}
}
You'll notice in the Android SDK Reference material for the AlarmManager.setRepeating() states:
Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.
You need to use AlarmManager.set() on pre-APIv19 and AlarmManager.setExact() on APIv19+. When your PendingIntent is fired and you receive your Broadcast in your BroadcastReceiver.onReceive() you can set another exact alarm for the next day.
Alarm Manager Example
I think you should follow above link. From my point of view, your design pattern (setting alarm in Activity class is not a good approach). Instead (like showed in the answer above) you should set your alarm from a service. Also the code for notification goes in BroadcastReceiver class, method OnReceive (In the example it is commented "Put here YOUR code").
Good luck
I have an app that sends a notification with AlarmManager every day at an exact time.
But it has a bug. The notification is sent whenever the app is open.
How can I get to the notification is send once a day? Thank you
MAINACTIVITY
public class MainActivity extends Activity {
private PendingIntent pendingIntent;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Calendar calendar = Calendar.getInstance();
int d = Integer.valueOf(1440);
calendar.setTimeInMillis(System.currentTimeMillis());
Intent i = new Intent(MainActivity.this, Receiver.class);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, i, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * d, pendingIntent);
}
}
RECEIVER
public class Receiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
Intent i = new Intent(context, MainActivity.class);
Notification notification = new Notification(R.drawable.ic_launcher,"This is a test message!", System.currentTimeMillis());
long[] vibrate = {100, 100, 200, 300};
notification.vibrate = vibrate;
notification.defaults = Notification.DEFAULT_ALL;
i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP| Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(context, 0, i,PendingIntent.FLAG_UPDATE_CURRENT);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(context, "AlarmManagerDemo", "This is a test message!", pendingNotificationIntent);
notificationManager.notify(0, notification);
}
}
Code to call CallThisClass.class every int d mins
Intent myIntent = new Intent(getActivity(), CallThisClass.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
int d = Integer.valueOf(duration);
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 2);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * d, pendingIntent);
Code to stop calling CallThisClass.class
Intent myIntent = new Intent(getActivity(), CallThisClass.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 0, myIntent, 0);
alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
CallThisClass.class
public class CallThisClass extends BroadcastReceiver {
#Override
public void onReceive(final Context context, Intent intent) {
Log.i("Received", "Broadcast Received !");
// Do your stuff
}
}
Dont forget Receiver inyour AndroidManifest.xml
<receiver android:name=".CallThisClass" />
And Permission
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
You can start calling CallThisClass.class whenever you want. Eg. on a click of a button, or when your main activity start. Just make sure to Stop Calling the class when you dont want it working. Eg You want when the user first installs your application you want every 24 hours there should be something updated (notification or something), rit? in your prefrences store a variable that changes itself only if it is loaded for the first time. Check for that variable every time user enters application. if it is first time Start the Calling code. (now we dont want to call the stop code yet because we cant to keep on calling that class even if the application is closed!) close the application and it will work. And you can have a button in you setting or something for testing that when clicked will run code for not calling the class. It will stop the calling calling class every d mins i.e 24 hours in your case (also you can change the prefrnce to default value on clik of this button so that next time you start activity or click activate or something again that code to start calling that class starts). I hope it helps.
Also, i would suggest a read here for Best practices
I'm making an android application.... and I've been trying to write the code for a daily notification set for a specific time of day. At first, I really thought this would be an easy task, almost every app in the play store has a timed notification. But after searching over and over again, all the methods and Youtube tutorials I've found failed to work for me. The problem probably lies in me, but I don't know what it is. All I need is a simple, elegant, easy to understand method (if there is such a thing). Any help would be greatly appreciated.
All the searching I've done has gotten me this far... but still without any luck:
This method is in my MainActivity class and is called only the first time the app is launched to set the alarm...
private void alarmMethod() {
Intent myIntent = new Intent(this, NotifyService.class);
AlarmManager alarmMgr = (AlarmManager) getSystemService(ALARM_SERVICE);
pendingIntent = PendingIntent.getService(this, 0, myIntent, 0);
// Set the alarm to start at approximately 2:00 p.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 14);
// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
Toast.makeText(MainActivity.this, "Start Alarm", Toast.LENGTH_LONG)
.show();
This is my NotifyService class:
package com.OHS.example;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
public class NotifyService extends Service {
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationManager mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Intent intent1 = new Intent(this.getApplicationContext(), MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent1, 0);
Notification mNotify = new NotificationCompat.Builder(this)
.setContentTitle("Title")
.setContentText("Hello World!")
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent)
.setSound(sound)
.build();
mNM.notify(1, mNotify);
}
}
Try This Code.
XML layout :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="#+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android Alarm Example:\n\rSetup an alarm event after 10 seconds from the current time. So just press Setup Alarm button and wait for 10 seconds. You can see a toast message when your alarm time will be reach." />
<Button
android:id="#+id/setAlarm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/TextView1"
android:layout_centerHorizontal="true"
android:layout_marginTop="25dp"
android:onClick="onClickSetAlarm"
android:text="Set Alarm" />
Main Activity :
public class MainActivity extends Activity {
//used for register alarm manager
PendingIntent pendingIntent;
//used to store running alarmmanager instance
AlarmManager alarmManager;
//Callback function for Alarmmanager event
BroadcastReceiver mReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Register AlarmManager Broadcast receive.
RegisterAlarmBroadcast();
}
public void onClickSetAlarm(View v)
{
//Get the current time and set alarm after 10 seconds from current time
// so here we get
alarmManager.set( AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10000 , pendingIntent );
}
private void RegisterAlarmBroadcast()
{
Log.i("Alarm Example:RegisterAlarmBroadcast()", "Going to register Intent.RegisterAlramBroadcast");
//This is the call back function(BroadcastReceiver) which will be call when your
//alarm time will reached.
mReceiver = new BroadcastReceiver()
{
private static final String TAG = "Alarm Example Receiver";
#Override
public void onReceive(Context context, Intent intent)
{
Log.i(TAG,"BroadcastReceiver::OnReceive() >>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
Toast.makeText(context, "Congrats!. Your Alarm time has been reached", Toast.LENGTH_LONG).show();
}
};
// register the alarm broadcast here
registerReceiver(mReceiver, new IntentFilter("com.myalarm.alarmexample") );
pendingIntent = PendingIntent.getBroadcast( this, 0, new Intent("com.myalarm.alarmexample"),0 );
alarmManager = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
}
private void UnregisterAlarmBroadcast()
{
alarmManager.cancel(pendingIntent);
getBaseContext().unregisterReceiver(mReceiver);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
protected void onDestroy() {
unregisterReceiver(mReceiver);
super.onDestroy();
}
}
I Hope this will help you, this worked for me.
You can always calculate and set the time when you want to trigger the alarm.
Happy Coding !!
You could use AlarmManager to schedule the daily notification. The document here provide a good explanation and example.
Setup the alarm.
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getService(this, 0,
new Intent(this, MainService.class),
PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
// set the triggered time to currentHour:08:00 for testing
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 8);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), 0, pendingIntent);
Service to handle the alarm.
public class MainService extends IntentService {
public MainService() {
super("mainservice");
}
public MainService(String name) {
super(name);
}
/*
* (non-Javadoc)
*
* #see android.app.IntentService#onHandleIntent(android.content.Intent)
*/
#Override
protected void onHandleIntent(Intent intent) {
showNotification();
}
private void showNotification() {
Uri soundUri = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("Alarm title")
.setContentText("Alarm text")
.setContentIntent(
PendingIntent.getActivity(this, 0, new Intent(this,
SecondActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT))
.setSound(soundUri).setSmallIcon(R.drawable.ic_launcher)
.build();
NotificationManagerCompat.from(this).notify(0, notification);
}
}
as alijandro said if you want to have a daily notification in specific time you could use AlarmManager to schedule it and at that time show notification or if you want to get data from server, send a http request to retrieve your data and show notification to the user.
But if you want to have push notification anytime you want, you could use GCM (Google Cloud Messaging). Look at this doc.
how to get notification in status bar at a particular time, i tried this, but every particular time the pendingIntents activity is bein called. I want the status bar's notification to be invoked. please help
public class MainActivity extends ActionBarActivity {
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);
Notification("abduct: ","kidnap");
}
#SuppressWarnings("deprecation")
private void Notification(String notificationTitle, String notificationMessage)
{
NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new Notification(R.drawable.icon, "First word", 50000);
notification.setLatestEventInfo(MainActivity.this, notificationTitle, notificationMessage, null);
notificationManager.notify(1, notification);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), 1*60*60 , pendingIntent ); //set repeating every 24 hours
}
}
The problem is with the PendingIntent you are providing the AlarmManager. By creating it with PendingIntent.getActivity() you're actually instructing it to start your activity when the specified time elapses.
What you need to do is:
Create a BroadcastReceiver and configure it in your AndroidManifest.xml file.
Instead of what you're currently doing, supply the AlarmManager with a PendingIntent to send a broadcast to this receiver (with PendingIntent.getBroadcast()).
In the receiver's onReceive(), build and show the notification.
You can find a clear and concise tutorial here.
this is my code for menage a single notification:
myActivity.java
public class myActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mylayout);
cal = Calendar.getInstance();
// it is set to 10.30
cal.set(Calendar.HOUR, 10);
cal.set(Calendar.MINUTE, 30);
cal.set(Calendar.SECOND, 0);
long start = cal.getTimeInMillis();
if(cal.before(Calendar.getInstance())) {
start += AlarmManager.INTERVAL_FIFTEEN_MINUTES;
}
Intent mainIntent = new Intent(this, myReceiver.class);
pIntent = PendingIntent.getBroadcast(this, 0, mainIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager myAlarm = (AlarmManager)getSystemService(ALARM_SERVICE);
myAlarm.setRepeating(AlarmManager.RTC_WAKEUP, start, AlarmManager.INTERVAL_FIFTEEN_MINUTES, pIntent);
}
}
myReceiver.java
public class myReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context c, Intent i) {
Intent myService1 = new Intent(c, myAlarmService.class);
c.startService(myService1);
}
}
myAlarmService.java
public class myAlarmService extends Service {
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#SuppressWarnings("deprecation")
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
displayNotification();
}
#Override
public void onDestroy() {
super.onDestroy();
}
public void displayNotification() {
Intent mainIntent = new Intent(this, myActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, mainIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager nm = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder builder = new Notification.Builder(this);
builder.setContentIntent(pIntent)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_noti)
.setTicker(getString(R.string.notifmsg))
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.notifmsg));
nm.notify(0, builder.build());
}
}
AndroidManifest.xml
<uses-permission android:name="android.permission.WAKE_LOCK" />
...
...
...
<service android:name=".myAlarmService" android:enabled="true" />
<receiver android:name=".myReceiver"/>
IF the time has NOT past yet everything works perfectly. The notification appears when it must appear.
BUT if the time HAS past (let's assume it is 10.31 AM) the notification fires every time... when I close and re-open the app, when I click on the notification... it has a really strange behavior.
I can't figure out what's wrong in it. Can you help me please (and explain why, if you find a solution), thanks in advance :)
Place display notification inside an if statement , such that compare the current time with the notification set time and if the current time is before the set time then display notification, else do nothing.
int temp = calTemp.getTime().compareTo(calendar.getTime());
if(temp > 0){
}else{
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(),
pendingIntent1);
}
here calTemp gives current time and calender gives the time i want to fire the alarm. So according to above code if the time has already past then the notification will not fire for sure .
Hi I've had the same problem and found a solution in this SO post, basically the idea is to rely on AlarmManager, Receiver but avoid usage of Service.
Since you are using the Service just to build and display the notification you may find useful my approach.
Let me know.