I have written this class to call reciver every 24 hours
I was trying to use same receiver for "SabahReceiver" then i added another receiver "MasaReceiver", all possibilities did not work for me!
anybody can tell me whats going wrong !?
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.mbh.test.receivers.MasaReciever;
import com.mbh.test.receivers.SabahReciever;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* Created by MBH on 17/12/15.
*/
public class SabahMasaAlarmManager {
public static final int MINUTE = 60000;
public static final int HOUR = 1000 * 60 * 60;
public static final int DAY = 86400000;
private PendingIntent mSabahPendingIntent;
private PendingIntent mMasaPendingIntent;
private Context mContext;
private void SetupAlarms() {
/* Retrieve a PendingIntent that will perform a broadcast */
Intent sabahAlarm = new Intent(mContext, SabahReciever.class);
// sabahAlarm.putExtra(SabahReciever.KEY_IS_SABAH, true);
mSabahPendingIntent = PendingIntent.getBroadcast(mContext, 100, sabahAlarm, 0);
/* Retrieve a PendingIntent that will perform a broadcast */
Intent masaAlarm = new Intent(mContext, MasaReciever.class);
// sabahAlarm.putExtra(SabahReciever.KEY_IS_SABAH, false);
mMasaPendingIntent = PendingIntent.getBroadcast(mContext, 101, masaAlarm, 0);
}
public void StartAlarm() {
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss" );
Date now = Calendar.getInstance().getTime();
Calendar sabahDate = Calendar.getInstance();
sabahDate.set(Calendar.HOUR_OF_DAY, 23);
sabahDate.set(Calendar.MINUTE, 47);
sabahDate.set(Calendar.SECOND, 0);
// sabahDate.set(Calendar.HOUR_OF_DAY, 6);
// sabahDate.set(Calendar.MINUTE, 0);
if(sabahDate.getTime().before(now)){
sabahDate.add(Calendar.DAY_OF_YEAR, 1);
}
Log.d("DATE", "Sabah: "+ dateFormat.format(sabahDate.getTime()));
Calendar masaDate = Calendar.getInstance();
masaDate.set(Calendar.HOUR_OF_DAY, 23);
masaDate.set(Calendar.MINUTE, 49);
// masaDate.set(Calendar.HOUR_OF_DAY, 20);
// masaDate.set(Calendar.MINUTE, 0);
masaDate.set(Calendar.SECOND, 0);
if(masaDate.getTime().before(now)){
masaDate.add(Calendar.DAY_OF_YEAR, 1);
}
Log.d("DATE", "Masa: "+ dateFormat.format(masaDate.getTime()));
AlarmManager manager = (AlarmManager) mContext.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, sabahDate.getTimeInMillis(), DAY, mSabahPendingIntent);
// manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+10000, 86400000, mSabahPendingIntent);
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, masaDate.getTimeInMillis(), DAY, mMasaPendingIntent);
// manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+20000, 86400000, mMasaPendingIntent);
}
public void cancelAlarm() {
AlarmManager managerSabah = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
managerSabah.cancel(mSabahPendingIntent);
AlarmManager managerMasa = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
managerMasa.cancel(mMasaPendingIntent);
}
public SabahMasaAlarmManager(Context baseContext) {
mContext = baseContext;
SetupAlarms();
}
}
setInexactRepeating() is not bound to fire the alarm exactly after the mentioned time. There may be some delay or it may fire a bit early. Basically framework 'batch' the inexact alarms to fire all at one time. Use setExact. Also consider the deep sleep mode. See How to use CPU to perform any operation in deep sleep mode. As you want alarm to fire once in 24 hours, there are good chances that device will be in sleep mode when alarm fires.
Related
I'm setting up a daily alarm. It works if the app is running at alarm time, but does not work if the app is not running.
This is how I declare the receiver in the Manifest:
<receiver android:name="com.myAppPackage.alarm.AlarmReceiver"
android:enabled="true"
android:exported="true"/>
Studio warns me: Exported receiver does not require permission.
True I have not added an android:permission nor and Intent to the receiver and the application section doesn't have any permission tags.
And this is the broadcastreceiver:
package com.myAppPackage.alarm;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
public class AlarmReceiver extends BroadcastReceiver {
public AlarmReceiver(){}
#Override
public void onReceive(Context context, Intent intent) {
final Intent syncIntent = new Intent(context, AlarmActivity.class);
syncIntent.addFlags(FLAG_ACTIVITY_NEW_TASK);
context.startActivity(syncIntent);
}
}
The alarm is configured in the following method (in this example configured to set-off daily inexact at 13:48):
public static void configureDailySync(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(context, AlarmReceiver.class);
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
final int hourOfDay = 13;
final int minuteOfHour = 48;
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
calendar.set(Calendar.MINUTE, minuteOfHour);
alarmManager.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY,
alarmPendingIntent);
}
Any help is very welcome! Thank you!!
news: getting closer... if I copy the alarm-setting code in the MainActivity onCreate() method it works! This is the code I copied:
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
final int hourOfDay = 13;
final int minuteOfHour = 48;
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
calendar.set(Calendar.MINUTE, minuteOfHour);
alarmManager.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY,
alarmPendingIntent);
When the alarm is created as above in the onCreate() of the MainActivity then it DOES trigger even when the app is closed...
But when I call the call the method from the MainActivity like this:
MyAppAccount.configureDailySync(this);
it doesn't work!
MyAppAccount is an plain class not extending anything... I've tried to have MyAppAccount extend AppCompatActivity in case it mattered but nothing...
Oh well... it seems that the above try of executing the alarm-setting in the onCreate() method of the MainActivity is not always working... what is most puzzling!!! :-(
SOLVED: It had nothing to do with coding!! The problem was the way I was closing the application. When closing the application using the stop button of Android Studio the alarm is NOT set. When closing the application from the phone, using the back button for instance and / or removing the application from the list of applications (with the square button), then the alarm works!
Why? No idea...
I really need help guys , i'm trying to make a toast appear at a specific time with the alarm manager from android . I made some research and i made this code , but i don't know what isn't ok ... I tried everything
public void start() {
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Date dat = new Date();
Calendar cal_alarm = Calendar.getInstance();
Calendar cal_now = Calendar.getInstance();
cal_now.setTime(dat);
cal_alarm.setTime(dat);
cal_alarm.set(Calendar.HOUR_OF_DAY,12);
cal_alarm.set(Calendar.MINUTE,13);
cal_alarm.set(Calendar.SECOND,0);
if(cal_alarm.before(cal_now)){
cal_alarm.add(Calendar.DATE,1);
}
manager.set(AlarmManager.RTC_WAKEUP,cal_alarm.getTimeInMillis(),pendingIntent);
}
If i use cal_alarm - cal_now in manager.set it fires off after 5 seconds .
You need to add a Receiver to get the result
In your AndroidManifest.xml add this
<receiver android:name=".AlarmReceiver" />
Create this BroadcastReceiver AlarmReceiver.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "ALARM", Toast.LENGTH_LONG).show();
}
}
and finally, fix your method start
public void start() {
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Date dat = new Date();
Calendar cal_alarm = Calendar.getInstance();
Calendar cal_now = Calendar.getInstance();
cal_now.setTime(dat);
cal_alarm.setTime(dat);
cal_alarm.set(Calendar.HOUR_OF_DAY,14);
cal_alarm.set(Calendar.MINUTE,18);
cal_alarm.set(Calendar.SECOND,0);
if(cal_alarm.before(cal_now)){
cal_alarm.add(Calendar.DATE,1);
}
Intent myIntent = new Intent(context, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(context, 0, myIntent, 0);
manager.set(AlarmManager.RTC_WAKEUP,cal_alarm.getTimeInMillis(), pendingIntent);
}
I have a set of alarms that I need to keep after reboot. I've tried using on an boot receiver but they won't start again. I'm not sure if I understand the boot receiver and how to then restart all the alarms. I already have one receiver for my notifications, but don't know whether I can use the same receiver or if I need a new one?
Could anyone point me to any good tutorials or help me out?
Cheers
Code :
DatabaseHandler db = new DatabaseHandler(this);
List<UAlarm> alarms = db.getAllAlarms();
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
for (UAlarm ua : alarms) {
String programme = ua.getTitle();
String startTime = ua.getStart();
String endTime = ua.getEnd();
String nowPlaying = ua.getChannel();
db.addAlarm(new UAlarm(programme, startTime, endTime, nowPlaying, ""));
final UAlarm ut = new UAlarm();
ut.setTitle(programme);
ut.setStart(startTime);
ut.setEnd(endTime);
ut.setChannel(nowPlaying);
ut.setId(db.getLastEntered());
String [] bla = startTime.split(":");
int hour = Integer.parseInt(bla[0].trim());
int minute = Integer.parseInt(bla[1].trim());
minute -= 2;
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, minute);
Intent intenta = new Intent(this, NotificationMenu.class);
String name = programme;
intenta.putExtra("name", name);
intenta.putExtra("id", db.getLastEntered());
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, ua.getId(),
intenta, PendingIntent.FLAG_CANCEL_CURRENT);
am.set(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), pendingIntent);
}
}
with NotificationMenu being the notifications, which is why I'm using the AlarmManager
I'm not sure if I understand the boot receiver and how to then restart all the alarms.
Just call your code to call setRepeating() (or whatever) on AlarmManager.
For example, in this sample project, PollReceiver is set to receive BOOT_COMPLETED. In onReceive(), it reschedules the alarms:
package com.commonsware.android.schedsvc;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;
public class PollReceiver extends BroadcastReceiver {
private static final int PERIOD=5000;
#Override
public void onReceive(Context ctxt, Intent i) {
scheduleAlarms(ctxt);
}
static void scheduleAlarms(Context ctxt) {
AlarmManager mgr=
(AlarmManager)ctxt.getSystemService(Context.ALARM_SERVICE);
Intent i=new Intent(ctxt, ScheduledService.class);
PendingIntent pi=PendingIntent.getService(ctxt, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + PERIOD, PERIOD, pi);
}
}
i am having this code for setting multiple alarms for creating a reminder application .The code works fine when a single alarm is put. However when i set mutiple alarms I am getting only the first reminder and that too invoked when the alarm time of the last reminder is reached.
import java.util.Calendar;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
public class ReminderManager {
private Context mContext;
private AlarmManager mAlarmManager;
public ReminderManager(Context context) {
mContext = context;
mAlarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
}
public void setReminder(Long taskId, Calendar when) {
Intent i = new Intent(mContext, OnAlarmReceiver.class);
i.putExtra(RemindersDbAdapter.KEY_ROWID, (long)taskId);
PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
mAlarmManager.set(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), pi);
}
}
On alarm reciever i have
public class OnAlarmReceiver extends BroadcastReceiver {
private static final String TAG = ComponentInfo.class.getCanonicalName();
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Received wake up from alarm manager.");
long rowid = intent.getExtras().getLong(RemindersDbAdapter.KEY_ROWID);
WakeReminderIntentService.acquireStaticLock(context);
Intent i = new Intent(context, ReminderService.class);
i.putExtra(RemindersDbAdapter.KEY_ROWID, rowid);
context.startService(i);
}
}
Your code shows that you have hard coded the 2nd parameter of
PendingIntent.getBroadcast(c, 0, i, etc
As far as I am aware, this parameter is the identifier for your alarm. Use a different value for each alarm if you want to set multiple alarms.
Try
PendingIntent.getBroadcast(c, taskid, i, etc
Alternatively, I handled this by only ever setting one alarm at a time (the earliest one).
When that alarm is triggered I then set the alarm for the next one.
Is it possible to show calendar alert in android, so that on the specified date the alert should pop up and remind the user regarding the task.
Sorry, there isn't currently a calendar API in the SDK. You can however implement your own alarm with the AlarmManager showing your own UI at the time you schedule with it.
first of all to set the alert in calendar application you have to make the permit-ion :
Now, that the alarm receiver is set, lets take a look at the class that will set and cancel the alarms:
package SomeApp.SomeApp;
import java.util.Calendar;
import java.lang.String;
import android.app.AlarmManager;
import android.app.ListActivity;
import android.app.PendingIntent;
import android.os.Bundle;
import android.util.Log;
import android.content.Intent;
import android.widget.Toast;
/**
* When this code is run only one alert will be displayed even though 2 alerts were
* were setup (as one of them will be cancelled later on
*/
public class SomeApp extends ListActivity {
/* for logging - see my tutorial on debuggin Android apps for more detail */
private static final String TAG = "SomeApp ";
protected Toast mToast;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.alert_list);
try {
Calendar cal = Calendar.getInstance();
Intent intent = new Intent(SomeApp.this, AReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(this, 1234567, intent, 0);
PendingIntent sende2 = PendingIntent.getBroadcast(this, 123123, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis()+30000, sender); // to be alerted 30 seconds from now
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis()+15000, sende2); // to be alerted 15 seconds from now
/* To show how alarms are cancelled we will create a new Intent and a new PendingIntent with the
* same requestCode as the PendingIntent alarm we want to cancel. In this case, it is 1234567.
* Note: The intent and PendingIntent have to be the same as the ones used to create the alarms.
*/
Intent intent1 = new Intent(SomeApp.this, AReceiver.class);
PendingIntent sender1 = PendingIntent.getBroadcast(this, 1234567, intent1, 0);
AlarmManager am1 = (AlarmManager) getSystemService(ALARM_SERVICE);
am1.cancel(sender1);
} catch (Exception e) {
Log.e(TAG, "ERROR IN CODE:"+e.toString());
}
}
}
You will notice that this is only a "one-shot" alarm. If you want to set a repeating alarm, it is explained in Android's documentation. However, I will write on that too if there is demand for it. Now, let's examine the code. For setting an alarm, you will need 4 things:
The class that's setting the alarm
The class that will be called when the alarm "goes off"
The time at which the alarm should go off
A requestCode (which will use as a unique ID to identify the alarms) used in PendingIntent.
For cancelling an alarm, you need 3 things:
The class that set the alarm
The class that was to be called when the alarm "goes off"
The requestCode you used for PendingIntent object.
We have covered 2 things - the declaration of the receiver in our manifest file and the class that sets and cancels alarms. Now, we need to look at the class that will be called when the alarm goes off.
package someApp.someApp;
import java.util.Calendar;
import android.content.Context;
import android.content.BroadcastReceiver;
import android.util.Log;
import android.widget.Toast;
/** All receiver classes must extend BroadcastReceiver */
public class AReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context con, Intent in) {
try {
/* Display an alert */
Toast.makeText(con, "hello my jello ", Toast.LENGTH_LONG).show();
} catch (Exception r) {
Toast.makeText(con, "You were supposed to do something"
+" now but I can't retrieve what it was.",
Toast.LENGTH_SHORT).show();
Log.e("ALARM_RECEIVER", r.toString());
}
}
}
AND YOU are able to use this other ans also...
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_YEAR, 0);
cal.set(Calendar.HOUR_OF_DAY, 9);
cal.set(Calendar.MINUTE, 01);
cal.set(Calendar.SECOND, 0);
setAlarm(cal);
cal.set(Calendar.HOUR_OF_DAY, 12);
cal.set(Calendar.MINUTE, 30);
setAlarm(cal);
//etc
}
public void setAlarm(Calendar cal) {
try {
Intent intent = new Intent(Alarm.this, Alarm1.class);
PendingIntent sender = PendingIntent.getBroadcast(this, 1234567, intent, 0);
PendingIntent sende2 = PendingIntent.getBroadcast(this, 123123, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender); // to be alerted 30 seconds from now
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sende2); // to be alerted 15 seconds from now
/* To show how alarms are cancelled we will create a new Intent and a new PendingIntent with the
* same requestCode as the PendingIntent alarm we want to cancel. In this case, it is 1234567.
* Note: The intent and PendingIntent have to be the same as the ones used to create the alarms.
*/
Intent intent1 = new Intent(Alarm.this, Alarm1.class);
PendingIntent sender1 = PendingIntent.getBroadcast(this, 1234567, intent1, 0);
AlarmManager am1 = (AlarmManager) getSystemService(ALARM_SERVICE);
am1.cancel(sender1);
} catch (Exception e) {
Log.e(TAG, "ERROR IN CODE:"+e.toString());
}
}