I have done some research and tried to implement a one time alarm that sends a notification to the user, but for some reason I cannot understand, when the time comes, the alarm is not being activated. I think the onReceive method is not being called, but I don't know why, since it's the first time I try to implement an alarm.
=== Edit: it seems that the alarm's onReceive is working after all, I got the toast message "Alarm!!" at the right time (don't know why it didn't the first time I tested), but no notification was received, though... Any clues?
This is the code for the Alarm class:
public class Alarm extends BroadcastReceiver {
public static final String PREFS_FILE_NAME = MainActivity.PREFS_FILE_NAME;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// send notification
Toast.makeText(context, "Alarm!!", Toast.LENGTH_SHORT).show();
// API < 16 so have to use compat
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setContentTitle(context.getResources().getString(R.string.memo_test_ready))
.setContentText(context.getResources().getString(R.string.click_to_start));
Intent resultIntent = new Intent(context, UpcomingTest.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(UpcomingTest.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(123, mBuilder.build());
}
public void Set(Context context)
{
DatabaseHandler db = new DatabaseHandler(context);
MemoryTestLevel memoTestLevel = new MemoryTestLevel();
long timeInterval;
long memoryTest_dateTime;
String alarmMemoLevel;
List<Phrase> studyPhrasesList = db.getPhrasesWithState(Phrase.START_STUDYING);
if (studyPhrasesList.size() > 0 ){ // if there are any phrases here, update them; dateTime == level 1
alarmMemoLevel = "Level 1 ";
memoTestLevel = db.getMemoryTestLevelWithLevel(MemoryTestLevel.LEVEL_1);
timeInterval = memoTestLevel.getTimeInterval();
TestDateTimeCalculator datetimeCalc = new TestDateTimeCalculator();
memoryTest_dateTime = datetimeCalc.calculate(timeInterval);
for(Phrase phrase : studyPhrasesList){
phrase.setMemoryTestPending(memoTestLevel.getMemoryTest_id(), memoryTest_dateTime);
db.updatePhrase(phrase);
}
} else {
// if there are no phrases to be set at level 1, then get the lowest memoTest_datime of
// the ones that are pending
alarmMemoLevel = "next after L1 ";
memoryTest_dateTime = db.getLowestMemoTestDateTime();
}
/* 2. Set new Alarm
* 2.1. Determine which phrases will go into this new alarm */
List<Phrase> nextMemoryTestPhrases = db.getNextMemoryTestPhrases(memoryTest_dateTime);
for(Phrase phrase : nextMemoryTestPhrases) {
phrase.setState(Phrase.MEMORY_TEST_SCHEDULED);
db.updatePhrase(phrase);
}
// 2.3 set alarm for required dateTime
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, Alarm.class);
PendingIntent pendingInt = PendingIntent.getBroadcast(context, 0, intent, 0);
alarmMgr.set(AlarmManager.RTC_WAKEUP, memoryTest_dateTime, pendingInt);
// 2.4 save the alarm.dateTime in the preferences so it can be used in the "upcoming test" activity
SharedPreferences preferences = context.getSharedPreferences(PREFS_FILE_NAME, Context.MODE_PRIVATE);
Editor editor = preferences.edit();
editor.putLong("NEXT_TEST_DATETIME", memoryTest_dateTime);
SimpleDateFormat sdf = new SimpleDateFormat("EEE, MMM d, yyyy hh:mm");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(memoryTest_dateTime);
String nextTestDateStr = sdf.format(calendar.getTime());
Toast.makeText(context, "Alarm set to " + alarmMemoLevel + nextTestDateStr, Toast.LENGTH_LONG).show();
editor.commit();
}
public void Cancel(Context context)
{
Intent intent = new Intent(context, MyBroadcastReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}
And I have a broadcast receiver in case the phone is rebooted:
public class MyBroadcastReceiver extends BroadcastReceiver {
public static final String PREFS_FILE_NAME = MainActivity.PREFS_FILE_NAME;
#Override
public void onReceive(Context context, Intent intent) {
// TODO setup alarm again (get datetime from system)
Alarm alarm = new Alarm();
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
{
SharedPreferences preferences = context.getSharedPreferences(PREFS_FILE_NAME, Context.MODE_PRIVATE);
long nextTestDateInMillis = preferences.getLong("NEXT_TEST_DATETIME", 0);
if(nextTestDateInMillis > 0){
alarm.Set(context);
}
}
}
}
From the research I found, it seems that something is missing/wrong in my manifest. This is what I have there:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
The below is inside application:
<receiver android:name="liliana.phrasememo.util.MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:process=":remote" android:name="liliana.phrasememo.util.Alarm"/>
Also, if you see anything else that's wrong in my implementation of Alarm + Notification it would be brilliant to give me the heads up. Thank you very much :-)
to set alarm may be this code helps you
Intent myIntent = new Intent(yourcontext, Alarm.class);
PendingIntent pendingIntent = PendingIntent.getService(act, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)act.getSystemService(act.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE,22);
calendar.set(Calendar.SECOND, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
also you must implement service instead of broadcastreciever to run at alarm time
Thanks very much to answer posted here, what is missing in my code is the notification icon, which I have added like this:
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher) // this was missing
.setContentTitle(context.getResources().getString(R.string.memo_test_ready))
.setContentText(context.getResources().getString(R.string.click_to_start));
And in fact, if we look at the documentation, it does specify that the small icon must be in the notification:
Required notification contents
A Notification object must contain the following:
A small icon, set by setSmallIcon()
A title, set by setContentTitle()
Detail text, set by setContentText()
The LogCat does have a file not found error:
05-05 12:39:39.191: A/NetworkStats(89): Caused by: java.io.FileNotFoundException: /proc/net/xt_qtaguid/stats: open failed: ENOENT (No such file or directory)
But it doesn't cause any crashes so you might not realise it. I'm not sure anything could be added to the notification constructor itself that would allow the user to see right away that something is missing. I don't have very advanced Java knowledge.
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'm developing my first android app for a client. The launch is scheduled on Saturday, everything works all right... but one thing.
I need the app to connect to the client's website once every 3 days, download events' info, then show a notification and (in some cases) send an email.
What is happening right now is that the app doesn't show any notification, but sends multiple mails every day instead: that should mean that the Alarm fires multiple times per day instead of once every 3.
In my manifest, i have these two receivers:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
[...]
<receiver android:name=".Helper.AlarmDownload"/>
<receiver
android:name=".Helper.AlarmBootReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
AlarmDownload.java does many thing. They all work, so i won't annoy you with the full code. Just the end:
Intent intentToRepeat = new Intent(context, Caricamento.class);
intentToRepeat.putExtra(Costanti.string_notif_idcorso,notifica.getInt(Costanti.sp_notifiche_idcorso,0));
//set flag to restart/relaunch the app
intentToRepeat.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//Pending intent to handle launch of Activity in intent above
PendingIntent pendingIntent =
PendingIntent.getActivity(context, NotificationHelper.ALARM_TYPE_RTC, intentToRepeat, PendingIntent.FLAG_UPDATE_CURRENT);
//Build notification
String titolonotifica = notifica.getString(Costanti.sp_notifiche_titolonotifica,"");
String subtitolo = notifica.getString(Costanti.sp_notifiche_subtitolo,"");
Notification repeatedNotification = buildLocalNotification(context, pendingIntent,titolonotifica,subtitolo).build();
//Send local notification
NotificationHelper.getNotificationManager(context).notify(NotificationHelper.ALARM_TYPE_RTC, repeatedNotification);
[...]
public NotificationCompat.Builder buildLocalNotification(Context context, PendingIntent pendingIntent, String titolo, String subtitolo) {
NotificationCompat.Builder mBuilder;
mBuilder = new NotificationCompat.Builder(context, "fisicamente")
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.icona_app)
.setContentTitle(titolo)
.setContentText(subtitolo)
//.setStyle(new NotificationCompat.BigTextStyle()
//.bigText(testo))
.setAutoCancel(true)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setCategory(NotificationCompat.CATEGORY_EVENT);
return mBuilder;
}
So, the real issue should be in NotificationHelper.java:
public class NotificationHelper {
public static int ALARM_TYPE_RTC = 100;
private static AlarmManager alarmManager1;
private static PendingIntent alarmIntent1;
public static void scheduleRepeatingRTCNotification(Context context) {
SharedPreferences pref_login = context.getSharedPreferences(Costanti.SP_LOGIN, Context.MODE_PRIVATE);
Boolean primavolta = pref_login.getBoolean("primavolta",false);
//primavolta means first time
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
Random r1 = new Random();
int casuale1 = r1.nextInt(100);
calendar.set(Calendar.HOUR_OF_DAY, 11);
calendar.set(Calendar.MINUTE, casuale1);
if (primavolta && calendar.before(Calendar.getInstance())) calendar.add(Calendar.DAY_OF_MONTH, 1);
//I don't want to show the notification on the first login of the user, so i'm adding one day to the calendar.
Intent intent = new Intent(context, AlarmDownload.class);
alarmIntent1 = PendingIntent.getBroadcast(context, ALARM_TYPE_RTC, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager1 = (AlarmManager)context.getSystemService(ALARM_SERVICE);
alarmManager1.setInexactRepeating(AlarmManager.RTC,
calendar.getTimeInMillis(), 3 * AlarmManager.INTERVAL_DAY, alarmIntent1);
}
This is what i do in MainActivity.java, the first time the user logs in:
Boolean primavolta = preferenze.getBoolean("primavolta",false);
if (primavolta) {
//Apre il drawer
drawer.openDrawer(GravityCompat.START);
//Notifiche
NotificationHelper.scheduleRepeatingRTCNotification(getApplicationContext());
}
The drawer opens only during the first login, so the schedulerepeatingRTCNotification void doesn't fire more than once.
Any idea?
Thank you very much in advance!
Edited: there was a reference to a costant instead of 3 in the code.
I've been programming in Android for over a year but have never used notifications before, which I need for one of my apps.
In the app, there are events that can be set at different times. Obviously, the user can choose to change these times or add/remove events.
I plan to use notifications to notify the user 5 minutes before their event starts.
I've read through the Android developer docs for Building a Notification and Services (which I am also new to). I have decided to use Services because I figured that the notification would need to be shown even when the app not running. To help me, I have been referring to one particular SO answer as guidance.
I begun by experimenting a little with the notification builder classes in my NotificationService class like so:
public class NotificationService extends IntentService {
private static final int NOTIFICATION_ID = 1;
public NotificationService() {
super(NotificationService.class.getSimpleName());
}
#Override
protected void onHandleIntent(Intent intent) {
showNotification();
}
private void showNotification() {
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
this, NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentTitle("Test notification")
.setSmallIcon(R.drawable.ic_event_black_24dp)
.setContentText("Test description")
.setContentIntent(pendingIntent);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.notify(NOTIFICATION_ID, builder.build());
}
}
I also use the following to start this Service in the splash screen of my app:
Intent serviceIntent = new Intent(this, NotificationService.class);
startService(serviceIntent);
To display notifications at specific times, I've read about AlarmManager, mainly through SO questions like this one. I also know that to display multiple notifications, I would need different notification ids (like my constant NOTIFICATION_ID).
However, what I am unsure of is dynamically updating the times that notifications would be shown each time an event is added, removed, or its times changed.
Could someone provide me some guidance on how I could achieve this?
You implement notification part. For notify user at Specific time you should set AlarmManager. I paste whole code you need then explain each part:
public class AlarmReceiver extends WakefulBroadcastReceiver {
AlarmManager mAlarmManager;
PendingIntent mPendingIntent;
#Override
public void onReceive(Context context, Intent intent) {
int mReceivedID = Integer.parseInt(intent.getStringExtra(AddReminderActivity.EXTRA_REMINDER_ID));
// Get notification title from Reminder Database
ReminderDatabase rb = new ReminderDatabase(context);
ApiReminderModel reminder = rb.getReminder(mReceivedID);
String mTitle = reminder.getName();
// Create intent to open ReminderEditActivity on notification click
// handling when you click on Notification what should happen
Intent editIntent = YourActivity.createActivity(context, reminder.getChannelId(), reminder.getStartTime());
PendingIntent mClick = PendingIntent.getActivity(context, mReceivedID, editIntent, PendingIntent.FLAG_UPDATE_CURRENT);
// Create Notification
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_logo))
.setSmallIcon(R.drawable.ic_logo)
.setContentTitle(context.getResources().getString(R.string.app_name))
.setTicker(mTitle)
.setContentText(mTitle)
.setContentIntent(mClick)
.setSound(ringtoneUri)
.setAutoCancel(true)
.setOnlyAlertOnce(true);
NotificationManager nManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
nManager.notify(mReceivedID, mBuilder.build());
}
public void setAlarm(Context context, Calendar calendar, int ID) {
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// Put Reminder ID in Intent Extra
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra(AddReminderActivity.EXTRA_REMINDER_ID, Integer.toString(ID));
mPendingIntent = PendingIntent.getBroadcast(context, ID, intent, PendingIntent.FLAG_CANCEL_CURRENT);
// Calculate notification time
Calendar c = Calendar.getInstance();
long currentTime = c.getTimeInMillis();
long diffTime = calendar.getTimeInMillis() - currentTime;
// Start alarm using notification time
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + diffTime, mPendingIntent);
// Restart alarm if device is rebooted
ComponentName receiver = new ComponentName(context, BootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
public void cancelAlarm(Context context, int ID) {
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// Cancel Alarm using Reminder ID
mPendingIntent = PendingIntent.getBroadcast(context, ID, new Intent(context, AlarmReceiver.class), 0);
mAlarmManager.cancel(mPendingIntent);
// Disable alarm
ComponentName receiver = new ComponentName(context, BootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
}
As you see we have setAlarm which notify users at specific time. I also pass calendar instance which is initiated before ( assign a time which user should be notify).
Calendar mCalendar = Calendar.getInstance();
mCalendar.add(Calendar.DAY_OF_YEAR, 7);// assume you want send notification 7 days later
new AlarmReceiver().setAlarm(getApplicationContext(), mCalendar, id);
We have another method cancelAlarm. If you want to delete a Alaram just pass unique ID of Alarm (Which already used for creation of Alarm).
Also don't forget to add this Service to your AndroidManifest.xml:
<receiver android:name=".service.AlarmReceiver" />
There is only on thing remain When you reboot your device you should set AlarmsManager again so you need a BootRecivier service.
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!