i am developing a scheduling app in which user selects a time from listview like 9:30 P.M or any time which is in the list and hits the button stop schedule, what i want want to stop schedule at 9:30 when its 9:30 (i will cal update method in database and update the user end time) or which the user selects from the list, user can also stop multiple schedules at a same time, i tried to use Scheduling Repeating Alarms but did not find any solution.
Please help me how can i do this?.
This is code i am making alarm for specific time
#TargetApi(Build.VERSION_CODES.N)
public void scheduleAlarm(View view, String timeEnd,String id) {
StringTokenizer tokens = new StringTokenizer(timeEnd, ":");
String first = tokens.nextToken();
String second = tokens.nextToken();
StringTokenizer token = new StringTokenizer(second, " ");
String two = token.nextToken(); // just changing given time into like 9:30 to 9 and 30
AlarmManager am = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
android.icu.util.Calendar calendar = android.icu.util.Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(android.icu.util.Calendar.HOUR_OF_DAY, Integer.parseInt(first));
calendar.set(android.icu.util.Calendar.MINUTE, Integer.parseInt(two));
Intent intent = new Intent(getApplicationContext(), AlarmReciever.class);
intent.putExtra("ID",id);
intent.putExtra("EndTime",timeEnd);
PendingIntent sender = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
}
And this is the Broadcast Receiver its works but broadcast class trigger at same time when i give the time to alarm schedule not on the given time.
public class AlarmReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
SQLITEDBTABLE sqLiteDatabase = new SQLITEDBTABLE(context);
String id = intent.getStringExtra("ID");
String time_end = intent.getStringExtra("EndTime");
sqLiteDatabase.update(time_end, id);
/* sqLiteDatabase.deleteOlderData(laterId);
sqLiteDatabase.deleteInactive(laterId);
sqLiteDatabase.updateEmployee(laterId, "Inactive");*/
//Toast.makeText(context, "Alarm Triggered and SMS Sent", Toast.LENGTH_LONG).show();
}
}
Remove this line
calendar.setTimeInMillis(System.currentTimeMillis());
From the code..... Calendar.getInstance() is already up to date. So you have.
#TargetApi(Build.VERSION_CODES.N)
public void scheduleAlarm(View view, String timeEnd,String id) {
StringTokenizer tokens = new StringTokenizer(timeEnd, ":");
String first = tokens.nextToken();
String second = tokens.nextToken();
StringTokenizer token = new StringTokenizer(second, " ");
String two = token.nextToken(); // just changing given time into like 9:30 to 9 and 30
AlarmManager am = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
android.icu.util.Calendar calendar = android.icu.util.Calendar.getInstance();
calendar.set(android.icu.util.Calendar.HOUR_OF_DAY, Integer.parseInt(first));
calendar.set(android.icu.util.Calendar.MINUTE, Integer.parseInt(two));
Intent intent = new Intent(getApplicationContext(), AlarmReciever.class);
intent.putExtra("ID",id);
intent.putExtra("EndTime",timeEnd);
PendingIntent sender = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
Related
I am new to android programming. I am developing an app which has a local notification. I am using Alarmmanager to set a local notification.
When I set the same time to Alarmmanager onReceive is called once for that time. My pending intent is also different.
Here how I am setting alarm:
for(int i = 0; i < dosageDtoList.size();i++)
{
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
DosageDto dosageDto = dosageDtoList.get(i);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
String time = dosageDto.getReminderTime();
String dateTime = startDateStr + " " + time;
Date formattedDate = simpleDateFormat.parse(dateTime);
Calendar cal = Calendar.getInstance();
cal.setTime(formattedDate);
Intent notificationIntent = new Intent("android.media.action.DISPLAY_NOTIFICATION");
notificationIntent.addCategory("android.intent.category.DEFAULT");
notificationIntent.putExtra(Constants.POS,i);
notificationIntent.putExtra(Constants.END_DATE, endDateStr);
notificationIntent.putExtra(Constants.TITLE, userDrugDto.getUserName());
notificationIntent.putExtra(Constants.SUB_TITLE, userDrugDto.getDrugName());
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent broadcast = PendingIntent.getBroadcast(context, i, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if(alarmManager != null)
{
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, broadcast);
}
}
Here is my Receiver class:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// generating notification
}
}
If I set an alarm for these two dates and time
1. 01-June-2018 15:10
2. 01-June-2018 15:10
With different pending intent ideally onReceive should be called twice but it getting called once.
Am I missing something?
I could not explain my problem in the Title..Here's the detailed explanation of my problem :
I have an application where arrival time of trains are displayed.
I want to add a feature where User can create an alert if the train is 10-5 minutes away from station.
A form is displayed to create an alert (all the values are stored in DB).
alertID = db.insert_alerts(name,starttime,endtime,booleanrepeat);
I am using alarm manager to create the notification :
if (is_repeat.equals("true")) {
new AlertsReceiver().setRepeatAlarm(getApplicationContext(), mCalendar, (int)alertID ,10000);
} else if (is_repeat.equals("false")) {
new AlertsReceiver().setAlarm(getApplicationContext(), mCalendar,(int)alertID);
}
below is the Receiver class :
public class AlertsReceiver extends WakefulBroadcastReceiver {
private int alertId;
AlarmManager mAlarmManager;
PendingIntent mPendingIntent;
#Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
if(extras == null) {
Log.d("Service","null");
} else {
alertId= extras.getInt("alertId");
}
Intent intent1 = new Intent(context,MService.class);
intent1.putExtra("alertId", alertId);
context.startService(intent1);
}
public void setAlarm(Context context, Calendar calendar, int ID) {
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context,AlertsReceiver.class);
intent.putExtra("alertId", 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);
}
public void setRepeatAlarm(Context context, Calendar calendar, int ID, long RepeatTime) {
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Log.e("asetRepeat",ID+"");
Intent intent = new Intent(context, AlertsReceiver.class);
intent.putExtra("alertId", ID);
mPendingIntent = PendingIntent.getBroadcast(context, ID, intent, PendingIntent.FLAG_CANCEL_CURRENT);
// Calculate notification timein
Calendar c = Calendar.getInstance();
long currentTime = c.getTimeInMillis();
long diffTime = calendar.getTimeInMillis() - currentTime;
// Start alarm using initial notification time and repeat interval time
mAlarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + diffTime,
RepeatTime , mPendingIntent);
}
public void cancelAlarm(Context context, int ID) {
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Toast.makeText(context,"Cancelled"+ID,Toast.LENGTH_LONG).show();
// Cancel Alarm using Reminder ID
mPendingIntent = PendingIntent.getBroadcast(context, ID, new Intent(context, RiderAlertsReceiver.class), 0);
mAlarmManager.cancel(mPendingIntent);
}
}
In receiver I am starting a service where I am making a webservice call :
Once an alarm manager is set..A webservice call is made in background service to check the minutes in which train will arrive :
if the minutes < 10 minutes notification is displayed else the webservice call should run again
So, i place the webservice in timer which runs every 1 minute.
The issue is how to stop the timer once the notification is received.
Also, the every time the receiver is starting the same service so only one alert is working at one time.
The user can create multiple alerts and all alerts are stored in DB.
Please can any one tell me the best way to implement this feature.
Appreciate Help...!
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'm trying to make an app that fires notifications every time the user has to take a medicine.
ISSUE: I want to send a notification at a specific time. I searched on the Internet but I only found tutorials that explain how to send notifications after a specified interval of time. I have more times stored in an SQLite database and I want to fire a notification for every of them, like an alarm clock.
This is my setAlarm() function (If something is not clear, please ask):
public void setAlarm()
{
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);
char[] sTime = TimeBtn.getText().toString().toCharArray();
if(sTime[0] == '0')
{
calendar.set(Calendar.HOUR_OF_DAY, sTime[1]);
}
else
{
String tmp = "";
tmp += sTime[0];
tmp += sTime[1];
int hour = Integer.parseInt(tmp);
calendar.set(Calendar.HOUR_OF_DAY, hour);
}
if(sTime[3] == '0')
{
calendar.set(Calendar.MINUTE, sTime[4]);
}
else
{
String tmp = "";
tmp += sTime[3];
tmp += sTime[4];
int minute = Integer.parseInt(tmp);
calendar.set(Calendar.MINUTE, minute);
}
calendar.set(Calendar.SECOND, 0);
if(current.before(calendar))
{
calendar.add(Calendar.DATE, 1);
}
Intent intent = new Intent(this, AlarmReceiver.class);
medName = mName;
medFormat = mFormat;
PendingIntent pIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager aManager = (AlarmManager) getSystemService(ALARM_SERVICE);
aManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
}
This function splits the date in hour and minute values and sets them to the Calendar. Once running I get notifications with no title and text (I manage them in a static function that sends medicine data to the BroadcastReceiver class) and when I add a new alarm, it doesn't fire. Like I said before, I'd like to get notifications for each time value.
This is the BroadcastReceiver class:
public class AlarmReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
String[] data = AddMedicine.getData();
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(AddMedicine.NOTIFICATION_ID, notification);
AddMedicine.NOTIFICATION_ID++;
}
}
If anyone could solve my problem, I will really appreciate it. Thanks in advance!
EDIT: This is the getData() method, that provides name and format of the medicine in order to put them in the building of the notification:
public static String[] getData()
{
String[] data = {medName, medFormat};
return data;
}
medName and medFormat are global variables initialized inside the setAlarm() method.
You are using same REQUEST_CODE for your PendingIntent, which replacing other PendingIntent's.
Use different request codes (2nd parameter) for your PendingIntent.getBroadcast() method for every call.
You can use SharedPref to store one counter which will increment for each PendingIntent.
Example :-
int reminderRequestCode = sPrefs.getInt(KeyConstants.PREF_REMINDER_REQUEST_CODE, -1);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),
*reminderRequestCode*, myIntent,0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
SharedPreferences.Editor editor = sPrefs.edit();
editor.putInt(KeyConstants.PREF_REMINDER_REQUEST_CODE, ++reminderRequestCode);
editor.commit();
when I add a new alarm, it doesn't fire
You have to use a unique identifier (requestCode field of getBroadcastmethod) for each PendingIntent because you're using the same one ( 0 ) for all of the instances with the PendingIntent.FLAG_UPDATE_CURRENT so only the last created one will be fired.
I get notifications with no title and text
I think you have to use Intentextras to send datas to the AlarmReceiver because in your case data are changin before AlarmReceiver gets fired so you get wrong values.
I need help. Im new to android coding.
I have made task list, which I want to do specific things at time written in task.
Here is my task item
private long id;
private int mon;
private int tues;
private int wednes;
private int thurs;
private int fri;
private int satur;
private int sun;
private int profile;
Where I have days (monday,tuesday etc) which holds amount of minutes (for 10:00 its 600).
Following some tutorials I have alarm reciever
public class AlarmReciever extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
try {
Bundle bundle = intent.getExtras();
String message = bundle.getString("alarm_message");
Intent newIntent = new Intent(context, AlarmActivity.class);
newIntent.putExtra("profile", message);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(newIntent);
} catch (Exception e) {
Toast.makeText(context, "There was an error somewhere, but we still received an alarm", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
Its still unedited...
And then there is code which calls to make new tasks in alarm manager
// get a Calendar object with current time
Calendar cal = Calendar.getInstance();
// add 5 minutes to the calendar object
cal.add(Calendar.MINUTE, 5);
Intent intent = new Intent(ctx, AlarmReceiver.class);
intent.putExtra("alarm_message", "O'Doyle Rules!");
// In reality, you would want to have a static variable for the request code instead of 192837
PendingIntent sender = PendingIntent.getBroadcast(this, 192837, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Get the AlarmManager service
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
I dont understand how to specify in calendar, that I need new task repeating (for example) every monday at 10:00, and that when this happens, it calls new function, giving it "profile" variable to work with.
private void setProfile(Integer profile)
{
// Doing things with profile
}
take a look at the following code:
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent2 = new Intent(context, SampleAlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent2, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
// Set the alarm's trigger time to item hour
calendar.set(Calendar.HOUR_OF_DAY, NuevoItemActivity.hora.getCurrentHour());
calendar.set(Calendar.MINUTE, NuevoItemActivity.hora.getCurrentMinute());
// Set the alarm to fire , according to the device's clock, and to repeat once a day.
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, (PendingIntent) alarmIntent);
As you can see in last line, you are able to indicate AlarmManager.INTERVAL_DAY to repeat the PendingIntent.