I have created a class called "VIAlarmManager" and in there I create an AlarmManager and set some properties. But no matter what, the Alarm is not fired, am I doing something wrong ? I try to call an task that is repeated in an given interval (eg 1 Minuten / 2 Minutes / 15 Minutes) and it should also be executed while in sleep.
Here is my code:
public final class VIAlarmManager{
public static AlarmManager alarmManager;
public int freq = 60;
public VIAlarmManager(int freq_in_sec){
this.freq = freq_in_sec;
}
public void setFrequency(int freq_in_sec){
this.freq = freq_in_sec;
}
public void setAlarm(){
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.MINUTE, 1);
alarmManager = (AlarmManager) MainActivity.Context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(MainActivity.Context, VIAlarmManager.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.Context, 0, intent, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),1000 * 60 * 1, pendingIntent);
}
public void cancleAlarm(){
Intent intent = new Intent(MainActivity.Context, VIAlarm_Heartbeat.class);
PendingIntent sender = PendingIntent.getBroadcast(MainActivity.Context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) MainActivity.Context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
public static class VIAlarm_Heartbeat extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Log.w("AlarmManager", "Calling Heartbeat now");
MainActivity.beat.beat();
}
}}
My AndroidManifest contains this line:
<receiver android:name="com.videro.util.VIAlarmManager$VIAlarm_Heartbeat" android:enabled="true" ></receiver>
And in my main activity I call:
AlarmManager = new VIAlarmManager(60);
AlarmManager.setAlarm();
If its a simple Alarm you require, the classical way is to use an Activity with TimePicker to select the time and a BroadcastReceiver to kick the Alarm along with a Service to send Notification to the user.
Here is a working way on how you can do it! Hope it helps:)
Related
I have a code in which alarm manager starts a service. I have to cancel it with the specified time using a second alarm. Not a single solution that I've looked at works. My code is as follows:
void startAtInterval(int fromTime, int fromTimeMinute, int toTime, int toTimeMinute, int id1, int id2) {
// start alarm
AlarmManager alarmMgr = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
PendingIntent alarmIntent = PendingIntent.getService(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, fromTime);
calendar.set(Calendar.MINUTE, fromTimeMinute);
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
// stop alarm
AlarmManager alarmMgr1 = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
PendingIntent alarmIntent1 = PendingIntent.getService(getApplicationContext(), 1, intent, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar calendar1 = Calendar.getInstance();
calendar1.setTimeInMillis(System.currentTimeMillis());
calendar1.set(Calendar.HOUR_OF_DAY, toTime);
calendar1.set(Calendar.MINUTE, toTimeMinute);
alarmMgr1.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar1.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent1);
stopService(intent);
alarmMgr1.cancel(alarmIntent1);
}
I used FLAG_UPDATE_CURRENT and FLAG_CANCEL_CURRENT. I also tried to stopservice as I show in my code. I'm passing time from a configuration screen. I know it works because first alarm is always fired.
You should have the second alarm which cancels the service fire a BroadcastReceiver which then stops the service. This will ensure that the alarm will successfully stop the service under any circumstances, such as the app being closed.
AlarmManager alarmMgr1 = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
Intent intentCancelService= new Intent(getApplicationContext(), StopServiceReceiver.class);
PendingIntent alarmIntent1 = PendingIntent.getBroadcast(getApplicationContext(), StopServiceReceiver.REQUEST_CODE, intentCancelService, PendingIntent.GoTestAlarmReceiver);
Calendar calendar1 = Calendar.getInstance();
calendar1.setTimeInMillis(System.currentTimeMillis());
calendar1.set(Calendar.HOUR_OF_DAY, toTime);
calendar1.set(Calendar.MINUTE, toTimeMinute);
alarmMgr1.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar1.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent1);
Then make your BroadcastReceiver:
public class GoTestAlarmReceiver extends BroadcastReceiver {
public static final int REQUEST_CODE = 123123; //whatever code just unique
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, YourServiceClassHere.class);
context.stopService(i);
}
}
Make sure to declare the receiver in your manifest:
<receiver
android:name=".StopServiceReceiver"
android:enabled="true"
android:process=":remote" />
To stop any alarm manager you have to use this:
Intent intentS = new Intent(ctx,YourService.class);
intentS.addCategory("SOMESTRING_AS_TAG");
PendingIntent senderS = PendingIntent.getService(ctx, NDX, intentS, PendingIntent.FLAG_CANCEL_CURRENT);
am.cancel(senderS);
senderS.cancel();
//and this
PendingIntent senderSNew = PendingIntent.getService(ctx, NDX, intentS, 0);
am.cancel(senderSNew);
senderSNew.cancel();
where NDX is the same as started. That is 0 in your case. Or, much better, change your NDX to a some random contant number.
to stop:
Intent intent = new Intent(ctx,YourService.class);
intent.addCategory("SOMESTRING_AS_TAG");
ctx.stopService(intent);
I have a receiver inside a service as i need the scheduled alarm to work even when the activity is destroyed. This is what i have done.
/**
* Created by rishabh on 14/2/16.
*/
public class MyService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
public class MyReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Calendar c = Calendar.getInstance();
int hour=c.get(Calendar.HOUR_OF_DAY);
int minute=c.get(Calendar.MINUTE);
Calendar calendar = new GregorianCalendar(1990, 1, 1, hour, minute);
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm");
String date = sdf.format(calendar.getTime());
String str=date.charAt(0)+""+date.charAt(1)+""+date.charAt(3)+""+date.charAt(4);
String LOG_TAG="DevicePolicyAdmin";
Log.v(LOG_TAG, "Service Started");
MainActivity.minochaDevicePolicyManager.resetPassword(str, 0);
}
}
}
And to trigger the receiver the scheduling alarm is here
Intent intent3=new Intent(MainActivity.this,MyService.class);
startService(intent3);
Intent intent2 = new Intent(MainActivity.this, MyService.MyReceiver.class);
PendingIntent pintent = PendingIntent.getService(MainActivity.this, 0, intent2, 0);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), 60 * 1000, pintent);
The onReceive method in the MyService class only executes once. why? What could be the issue. Please help
Try moving MyReceiver to an independent file as public class and use this code to start.
Intent intent2 = new Intent(getApplicationContext(), MyReceiver.class);
PendingIntent pintent = PendingIntent.getService(getApplicationContext(), 0, intent2, 0);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), 60 * 1000, pintent);
Update 1 :
This may help you -How to repeat my service using alarm manager?
Update 2 : Check this too- Android - Periodic Background Service - Advice
you need to register it in service as follows,
IntentFilter filter = new IntentFilter();
filter.addAction("SOME_ACTION");
filter.addAction("SOME_OTHER_ACTION");
context.registerReceiver(receiver, filter);
Also in onReceive method you need to check for the action of broadcast receiver fired for.
Hope this will help you.
One of your problems is that your getting a service using the intent which use the broadcast receiver. Start changing this:
PendingIntent pintent = PendingIntent.getService(MainActivity.this, 0, intent2, 0);
For this:
PendingIntent pintent = PendingIntent.getService(MainActivity.this, 0, intent3, 0);
I'm using alarmmanager class to schedule notification for the user to lunch every day in a certain time but when th time comes it force stop the application
this is the setAlarm() method that i call onCreate of the main activity
public void setAlarm() {
// TODO Auto-generated method stub
AlarmManager alarmMgr;
PendingIntent alarmIntent;
alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
// Set the alarm to start at approximately 8:00 p.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 10);
calendar.set(Calendar.MINUTE, 17);
// 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,
alarmIntent);
}
and that's the the BroadcastReceiver Class
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
creatNotification(context, "Times Up", "5 Seconds Passed", "Alert");
}
private void creatNotification(Context context, String MSG, String MSgText, String MSGAlert) {
PendingIntent NotifIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0);
NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(context);
notifBuilder.setContentTitle("title").setContentText("Content")
.setTicker("Ticker").setSmallIcon(R.drawable.ic_launcher);
notifBuilder.setContentIntent(NotifIntent);
notifBuilder.setDefaults(NotificationCompat.DEFAULT_SOUND);
notifBuilder.setAutoCancel(true);
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, notifBuilder.build());
}
any Ideas ??
Did you define your Broadcast receiver on Manifest file?
I try to have a notification repeated daily (For debugging I set it to every 10s). However, it is firing the notification only the first time, then nothing happens.
Here is the code where the alarm is set:
Intent myIntent = new Intent(ctx , NotifyService.class);
AlarmManager alarmManager =(AlarmManager)ctx.getSystemService(ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getService(ctx, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(), 1000 * 10, pendingIntent);
and here is the service:
public class NotifyService extends Service {
public NotifyService() {
}
#Override
public void onCreate(){
//Create and Emit the notification.
}
I have tried different flags in getService(ctx, int, Intent, flags), to use setInexactRepeating and to set a new alarm after every call to the NotifyService.
Use the method below to repeating the alarm once in a day and you have to register broadcast receiver instead of service with AlarmManager so that you can start your service from the receiver and that is recommended.
Find the official doc.
private final static String ACTION = "ACTION_ALARM";
public static void setWakeUpAction(Context context, String hourSet, String minuteSet, String periodSet, int requestCode, String currentAction) {
try {
String mHour = hourSet;
String mMin = minuteSet;
String[] parsedFormat = null;
Calendar calendar = Calendar.getInstance();
SimpleDateFormat displayFormat = new SimpleDateFormat("HH:mm");
SimpleDateFormat parseFormat = new SimpleDateFormat("hh:mm a");
Date date = parseFormat.parse(mHour + ":" + mMin + " " + periodSet);
parsedFormat = displayFormat.format(date).split(":");
mHour = parsedFormat[0];
mMin = parsedFormat[1];
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(mHour));
calendar.set(Calendar.MINUTE, Integer.parseInt(mMin));
calendar.set(Calendar.SECOND, 00);
Intent myIntent = new Intent(context, MyReceiver.class);
myIntent.putExtra(ACTION, currentAction);
myIntent.putExtra("Time", new String[]{mHour, mMin, periodSet});
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, requestCode, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
} catch (ParseException e) {
e.printStackTrace();
}
}
BroadCastReceiver
public class MyReceiver extends BroadcastReceiver {
private final String ACTION = "ACTION_ALARM";
private String ACTION_ONE = "ALARM_REPEAT";
#Override
public void onReceive(Context context, Intent intent) {
try {
String action = intent.getStringExtra(ACTION);
new ShowToast(context, action);
if (action.length() > 1) {
if (action.equals(ACTION_ONE) ) {
String time[] = intent.getStringArrayExtra("Time");
startService(context, action);
}
}
} catch (Exception e) {
}
}
public void startService(Context context, String action) {
Intent service1 = new Intent(context, NotifyService.class);
service1.putExtra(ACTION, action);
context.startService(service1);
}
}
Manifest
<service
android:name=".NotifyService"
android:enabled="true" />
<receiver android:name=".MyReceiver" />
Usage
setWakeUpAction(context, "11", "00","AM","0", "ALARM_REPEAT");
Use a PendingIntent for a BroadcastReceiver rather than a Service, that is the recommended (and documented) practice. Plus, if you are using "wakeup" alarms, you'll need to use a BroadcastReceiver otherwise the system will not guarantee that it stays awake long enough for your Service to actually execute and receive the Intent. See this article for more details: http://po.st/7UpipA
Try this,
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
// setRepeating() lets you specify a precise custom interval--in this case,
// 10 seconds.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 10, alarmIntent);
Refer : http://developer.android.com/training/scheduling/alarms.html
I'm trying to broadcast after 20 seconds and receive the broadcast with an extended receiver ExtendedReceiver.
Here is my function that creates an alarm and sets the PendingIntent to go off after 20 seconds:
public void alert() {
GregorianCalendar cal = new GregorianCalendar();
cal.add(Calendar.SECOND, 20);
Intent i = new Intent(this, ExtendedReceiver.class);
int _uid = (int) System.currentTimeMillis();
PendingIntent pi = PendingIntent.getBroadcast(this, _uid, i, PendingIntent.FLAG_ONE_SHOT);
AlarmManager am = (AlarmManager)getSystemService(Activity.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pi);
Log.i("Title", "Alarm has been set");
}
Here is the ExtendedReceiver class:
public class ExtendedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("Title", "Broadcast received");
}
}
I get my first log message: Alarm has been set but I don't get my second log message. I'm unsure where the problem lies (first day on Android)
If i may this is what i always do.
change your
PendingIntent pi = PendingIntent.getBroadcast(this, _uid, i, PendingIntent.FLAG_ONE_SHOT);
to
PendingIntent pi = PendingIntent.getBroadcast(this, _uid, new Intent(EXTENDED_RECEIVER_ACTION), PendingIntent.FLAG_ONE_SHOT);
and important: Register your ExtendedReceiver like this:
...
registerReceiver(new ExtendedReceiver() , new IntentFilter(EXTENDED_RECEIVER_ACTION));
PS: EXTENDED_RECEIVER_ACTION is a String and dont forget to unregister your receiver.
further docs here
hope it helps :)