I am developing the schedule notification for Android. It is successfully get notification at scheduled time but also get notification at the time when the application startup which I do not want. Here are my codes.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
prefs= PreferenceManager.getDefaultSharedPreferences(this);
show = (TextView)findViewById(R.id.textView);
View btn_failure = findViewById(R.id.btn_failure_id);
btn_failure.setOnClickListener(this);
View btn_unhappy = findViewById(R.id.btn_unhappy_id);
btn_unhappy.setOnClickListener(this);
View btn_chicken_soup = findViewById(R.id.btn_soup_id);
btn_chicken_soup.setOnClickListener(this);
View btn_no_motivation = findViewById(R.id.btn_no_id);
btn_no_motivation.setOnClickListener(this);
// createScheduledNotification(9,0);
}
#Override
protected void onResume() {
super.onResume();
time = prefs.getString("noti", "9:00");
String[] pieces=time.split(":");
hour = Integer.parseInt(pieces[0]);
minute = Integer.parseInt(pieces[1]);
boolean onOff = prefs.getBoolean("noti_10",true);
createScheduleNotification(hour,minute,onOff);
}
public void createScheduleNotification(int hour, int minute, boolean onOff){
if(onOff){
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
AlarmManager am = (AlarmManager) MainActivity.this.getSystemService(MainActivity.this.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, getPendingIntent(this));
}else{
AlarmManager mgr=(AlarmManager)this.getSystemService(this.ALARM_SERVICE);
mgr.cancel(getPendingIntent(this));
}
}
private PendingIntent getPendingIntent(Context ctxt) {
Intent intent1 = new Intent(ctxt, TimeAlarm.class);
intent1.putStringArrayListExtra("quotes",quote_chicken_soup);
PendingIntent pendingIntent = PendingIntent.getBroadcast(ctxt, 0,intent1, PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
public class TimeAlarm extends BroadcastReceiver {
private String daily_quote = "testing";
#Override
public void onReceive(Context context, Intent paramIntent) {
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(context,DisplayActivity.class);
intent.putStringArrayListExtra("quote",paramIntent.getStringArrayListExtra("quotes"));
daily_quote = paramIntent.getStringArrayListExtra("quotes").get(0);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, 0);
Notification.Builder builder = new Notification.Builder(context);
builder.setAutoCancel(true);
builder.setTicker("Daily Quote");
builder.setContentTitle("Daily Quote");
builder.setContentText(daily_quote);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentIntent(pendingIntent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
builder.setSubText("Be Happy! Have a nice day!"); //API level 16
}
Notification myNotication = builder.getNotification();
manager.notify(11, myNotication);
}
}
Where is the problem that cause the notification being push when app startup?
There seems nothing wrong in your code.
Issue with notification being pushed up at startup is surely because of AlarmManager code.
From your code snippet, I hard coded the setting of time as below, and it runs as expected . First time it triggers in one minute after the system clock and then every 2 minutes there after.
// first time set to-- trigger after one minute from now
long firstTimeTriggerAt = SystemClock.elapsedRealtime() + 1000 * 60 * 1;
AlarmManager am = (AlarmManager) MainActivity.this.getSystemService(MainActivity.this.ALARM_SERVICE);
//Repeat the alaram every two minutes
long interval = 1000 * 60 * 2;
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,firstTimeTriggerAt, interval, getPendingIntent(this));
So you need to check the constant values for time, which you are setting in Shared preference.
Just FYI , the code runs well with RTC_WAKEUP constant also.
Hope this helps.
in onResume() change
boolean onOff = prefs.getBoolean("noti_10",true);
to
boolean onOff = prefs.getBoolean("noti_10",false);
Related
I am creating an android app in which user can add multiple babies, each baby have multiple dates on which alarm being called.
I am getting dates from SQLite Database After fetching dates, the alarm will be setting to those dates. I have set everything correctly, but alarm not working properly.
Here is the code .
List babyDataList = new ArrayList<>();
List listItems = new ArrayList<>();
Database db = new Database();
babyDataList = db.getAllBabies();
calendar = Calendar.getInstance();
calenderThird = Calendar.getInstance();
for(BabyModal b : babyDataList ){
String name = b.getBabyName();
String first = b.getFirstVac(); // FirstDate
String sec = b.getSecVac(); //SecondDate
String[] val1 = first.split("-");
int dateSec = Integer.parseInt(val1[0]);
int monthSec = Integer.parseInt(val1[1]);
int yearSec = Integer.parseInt(val1[2]);
calendar.set(
yearSec, monthSec-1, dateSec, 8, 30, 30
);
setAlarm(calendar);
String[] val2 = sec.split("-");
int dateThird = Integer.parseInt(val2[0]);
int monthThird = Integer.parseInt(val2[1]);
int yearThird = Integer.parseInt(val2[2]);
calenderThird.set(
yearThird, monthThird-1, dateThird, 8, 30, 30
);
setAlarm(calendarThird);
listItems.add(b);
}
The Method for setAlarm is
private void setAlarm(Calendar cal){
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
(int) cal.getTimeInMillis(), intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am =
(AlarmManager)getSystemService(Activity.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
pendingIntent);
}
AlarmReceiver class :
public class AlarmReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent intent1 = new Intent(context, MyNewIntentService.class);
context.startService(intent1);
}
}
MyNewIntentService class:
public class MyNewIntentService extends IntentService {
private static final int NOTIFICATION_ID = 3;
public MyNewIntentService(String name) {
super(name);
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
Notification.Builder builder = new Notification.Builder(this);
builder.setContentTitle("Vaccination Time");
builder.setContentText(" ");
builder.setSmallIcon(R.drawable.health);
builder.setVibrate(new long[] { 1000, 1000, 1000, 1000, 1000 });
builder.setLights(Color.RED, 3000, 3000);
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
builder.setSound(alarmSound);
PowerManager pm = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
boolean isScreenOn = pm.isScreenOn();
if(isScreenOn==false){
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |PowerManager.ACQUIRE_CAUSES_WAKEUP |PowerManager.ON_AFTER_RELEASE,"MyLock");
wl.acquire(10000);
PowerManager.WakeLock wl_cpu = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"MyCpuLock");
wl_cpu.acquire(10000);
}
Intent notifyIntent = new Intent(this, BabiesList.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 2, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//to be able to launch your activity from the notification
builder.setContentIntent(pendingIntent);
Notification notificationCompat = builder.build();
NotificationManagerCompat managerCompat = NotificationManagerCompat.from(this);
managerCompat.notify(NOTIFICATION_ID, notificationCompat);
}
}
Thanks in advance.
I am not gonna solve your problem whatever you have posted and wants to resolve; rather i would try to clear basics...
What is alarm manager
It is not the one which system uses for traditional alarms for waking up the persons from sleep, rather it is the same concept... but for the developers; who wants to wake up their piece of code at the specified time...
How to wake up my code then...
Note below code is working across 4.0 to the latest android P; tested on all
Calendar CalendarEvent = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
CalendarEvent.set(Calendar.HOUR_OF_DAY, 14);
CalendarEvent.set(Calendar.MINUTE, 00);
CalendarEvent.set(Calendar.SECOND, 00);
Log.d("SCHEDULER : ", "CALENDAR SET TIME :"+CalendarEvent.getTime()+"\n");
Intent myintent = new Intent(this, MyService.class);
PendingIntent pi = PendingIntent.getService(this, 0, myintent, 0);
AlarmManager alarm_manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm_manager.set(AlarmManager.RTC, CalendarEvent.getTimeInMillis(), pi);
What is this...??
Here HOUR_OF_DAY is set to 14 meaning 2PM in the afternoon as per your default timezone. On 2PM, it will start MyService and note it is not necessary that your application must remain in foreground or background or in recents...!! IT WILL GET CALLED...
What the permissions are needed
only <uses-permission android:name="android.permission.WAKE_LOCK" /> if you wants... Note that <uses-permission android:name="com.android.alarm.permission.SET_ALARM" /> is not necessary as it is intended for traditional alarms
What are the deadlines...?
Until next-boot these alarms are remembered by the android systems..!! On the next boot all the alarms are deleted by android system... It means if you set the alarm on 20 jan 2018 and if device is rebooted on the day before or even the timeinmillis before... android will forget it
How to remember it across every boot...?
Use a BOOT_COMPLETED intent for receiver with <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> permission and re-set all the alarms manually... again... with the help of database table
It is not the answer of my question which i asked....
Yes, it is. Implement this concept first in a sample new project. clear the concept with such a code which runs across the android platforms in the all cases you wants... And then implement it in the way you wants ... in the main projects.
Huuushhhh...
I want set the alarm at the specified time and implement the notification at the specified time(in a day) by using BroadcastReceiver and AlaramManager.
It alarmed specified time. After when I run the app, it again alarm even though it's not the time I set.
In other words, when I set the alarm 9:21 pm and I run the app after 9:21 pm, the notification is generated.
I just want to make the alarm notification at the specified time I set and app doesn't run.
Also, when I run the app, it doesn't alarm.
How can I fix it?
This is my BroadcastReceiver Code -
public class BroadcastD extends BroadcastReceiver{
Context context;
#Override
public void onReceive(Context context, Intent intent) {
this.context = context;
showNotification();
}
public void showNotification() {
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent pendingIntent = PendingIntent
.getActivity(context, 0, new Intent(context, MainActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setSmallIcon(android.R.drawable.ic_dialog_alert)
.setTicker("Ticket")
.setContentTitle("Title")
.setContentText("Context")
.setWhen(System.currentTimeMillis())
.setAutoCancel(true)
.setContentIntent(pendingIntent);
notificationManager.notify(1, builder.build());
}
}
This is my MainActivity code :
public class MainActivity extends AppCompatActivity {
AlarmManager am ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
am = (AlarmManager) getSystemService(ALARM_SERVICE);
AlarmHATT alarmHATT = new AlarmHATT(getApplicationContext());
alarmHATT.Alarm();
}
public class AlarmHATT {
private Context context;
public AlarmHATT(Context context) {
this.context = context;
}
public void Alarm() {
Intent intent = new Intent( context.getApplicationContext(), BroadcastD.class);
PendingIntent sender = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
calendar.get(Calendar.DATE), 21, 21, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 24*60*60*1000, sender);
}
}
To avoid having the alarm fire immediately, configure your start time with the Calendar like this:
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 30);
calendar.set(Calendar.SECOND, 0);
And then if the time you are setting has already passed today, you need to set the calendar to the following day with:
calendar.add(Calendar.DATE, 1);
That will avoid having your alarm fire immediately because it was set to a time that already passed earlier in the day.
Then continue to use calendar.getTimeInMillis() as your starting time.
Try below code to set alarm on a specified time.
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
I am currently trying to create a repeating alarm that goes off at the same time everyday following a tutorial however I cannot seem to get it working. It goes off but as soon as the application launches instead of the set time I am not sure what the reason is. I also made sure the service was declared in manifest. Any idea where I am going wrong or if this the right way to go about something like this?
Main acitivty
public class MainActivity extends AppCompatActivity {
private PendingIntent pendingIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();
int i = preferences.getInt("numberofLaunces", 1);
if (i < 2) {
alarmMethod();
i++;
editor.putInt("numberoflaunches", i);
editor.commit();
}
if (savedInstanceState == null) {
return;
}
}
private void alarmMethod() {
Intent myIntent = new Intent(this, NotifyService.class);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
pendingIntent = PendingIntent.getService(this, 0, myIntent, 0);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 32);
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.AM_PM, Calendar.AM);
calendar.set(Calendar.DAY_OF_MONTH, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 60 * 24, pendingIntent);
Toast.makeText(MainActivity.this, "start Alarm", Toast.LENGTH_LONG).show();
}
}
Notifyservice
public class NotifyService extends Service {
#Override
public IBinder onBind(Intent Intent) {
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 Notification.Builder(this)
.setContentTitle("placeholder tital")
.setContentText("Placeholder text")
.setSmallIcon(R.drawable.ic_cat)
.setContentIntent(pIntent)
.setSound(sound)
.addAction(0,"hello", pIntent)
.build();
mNM.notify(1, mNotify);
}
}
From developer [site](http://developer.android.com/reference/android/app/AlarmManager.html#set(int, long, android.app.PendingIntent))
The alarm is an Intent broadcast that goes to a broadcast receiver that you registered with registerReceiver(BroadcastReceiver, IntentFilter) or through the tag in an AndroidManifest.xml file.
You should define broadcast pending intent instead of service.
Change this
Intent myIntent = new Intent(this, NotifyService.class);
pendingIntent = PendingIntent.getService(this, 0, myIntent, 0);
To this
Intent myIntent = new Intent(this, MyAlarmBroadcastReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, myIntent, 0);
Then implement MyAlarmBroadcastReceiver extends BroadcastReceiver class and fire notification inside onReceive().
The problem is quite simple: If the time a alarm should fire (the second parameter in setRepeating()) is in the past, it will fire immediately. The time you specified is 0:32 am in the night of the 0th (?) day of the month.
This is always in the past (maybe except for 32 minutes every month, though I don't know what the 0th day of the month is).
To fire the alarm every 24 hours at the time of 0:32 am use something like this:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.MINUTE, 32);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.AM_PM, Calendar.AM);
calendar.add(Calendar.DAY_OF_MONTH, new Date().after(calendar.getTime()) ? 1 : 0); //if the current time is after 0:32 am, one day is added
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 60 * 24, pendingIntent);
I'm trying to make an an app that sends multiple scheduled alarms, shown through a notification according to a specific time (not time interval, but time) every day.
I already implemented the AlarmReceiver.class that fires the notifications at each intent, but the problem is that I don't get any notification. I tried to show a Log inside the onReceiver() method, but the message hasn't been shown, so the alarm hasn't been reached.
This is the setAlarm() function, that sets the hour and the time to the Calendar I instantiated:
public void setAlarm()
{
SharedPreferences pref = this.getSharedPreferences("NOTIFICATION_CODE", Context.MODE_PRIVATE);
String mName = NameFld.getText().toString();
String mFormat = FormatSpn.getSelectedItem().toString();
Date date = new Date();
Calendar calendar = Calendar.getInstance();
Calendar current = Calendar.getInstance();
current.setTime(date);
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, picker_hour);
calendar.set(Calendar.MINUTE, picker_minute);
calendar.set(Calendar.SECOND, 0);
if(current.before(calendar))
{
calendar.add(Calendar.DATE, 1);
}
medName = mName;
medFormat = mFormat;
int _reqCode = pref.getInt("reqCode", -1);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pIntent = PendingIntent.getBroadcast(this, _reqCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager aManager = (AlarmManager) getSystemService(ALARM_SERVICE);
aManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
editor = pref.edit();
editor.putInt("reqCode", ++_reqCode);
editor.commit();
}
To set the time, I implemented a TimePickerDialog and I stored hour and minute values to picker_hour and picker_minute.
Since I have to send multiple alarms, I use SharedPreferences to store the reqCode used then to identify the PendingIntent every time one is sent.
This is the AlarmReceiver.class that fire a notification for each intent received. Every notification is identified through the same reqCode of the PendingIntent:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String[] data = AddMedicine.getData();
SharedPreferences pref = context.getSharedPreferences("NOTIFICATION_CODE", context.MODE_PRIVATE);
int reqCode = pref.getInt("reqCode", -1);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setAutoCancel(true);
builder.setTicker("It's pill time!");
builder.setContentTitle(data[0]);
builder.setContentText(data[1]);
builder.setSmallIcon(R.drawable.ic_launcher);
Notification notification = builder.build();
NotificationManager nManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
nManager.notify(reqCode, notification);
Log.i("NOTIFICATION", "FIRED!");
}}
P.s. The alarm is set every time the user creates it, in order to schedule them through the reqCode.
So, anyone knows how to send multiple alarms according by time? Thank you in advance!
I want to make an app that sends scheduled notifications every day according to specific times inserted by the user.
The problem is that when I launch the app I get one or two notifications randomly and I don't receive them at the set time.
Here is my setAlarm() function called when the user clicks a button:
public void setAlarm()
{
String mName = NameFld.getText().toString();
String mFormat = FormatSpn.getSelectedItem().toString();
Date date = new Date();
Calendar calendar = new GregorianCalendar();
Calendar current = new GregorianCalendar();
current.setTime(date);
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, picker_hour);
calendar.set(Calendar.MINUTE, picker_minute);
calendar.set(Calendar.SECOND, 0);
if(current.before(calendar))
{
calendar.add(Calendar.DATE, 1);
}
medName = mName; // Used to build the notification (it doesn't matter for now).
medFormat = mFormat; // Used to build the notification (it doesn't matter for now).
long when = calendar.getTimeInMillis();
Intent intent = new Intent(AddMedicine.this, AlarmReceiver.class);
final int _id = (int) System.currentTimeMillis(); // PendingIntent id.
PendingIntent pIntent = PendingIntent.getBroadcast(AddMedicine.this, _id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager aManager = (AlarmManager) getSystemService(ALARM_SERVICE);
aManager.set(AlarmManager.RTC_WAKEUP, when, pIntent);
}
And here is my BroadcastReceiver class:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String[] data = AddMedicine.getData(); // Used to build the notification (it doesn't matter for now).
// Notification building.
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setAutoCancel(true);
builder.setTicker("It's pill time!");
builder.setContentTitle(data[0]);
builder.setContentText(data[1]);
builder.setSmallIcon(R.drawable.ic_launcher);
Notification notification = builder.build();
NotificationManager nManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
nManager.notify(0, notification);
Log.i("NOTIFICATION", "The notification has been fired."); // Used to see if the alarm ha really been received.
}}
Can anyone elaborate something to fix this up? Thank you in advance for any help!