I am trying to implement repeating multiple alarms at different specific times.
The problem is the Alarm Receiver is not getting invoked at any given time.
My code in the activity:
private void setAlarms() {
Intent myIntent=new Intent(this, AlarmReceiver.class);
myIntent.putExtra("MedName",medication_name);
myIntent.setAction("b5.project.medibro.receivers.AlarmReceiver");
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
//am.set(AlarmManager.RTC_WAKEUP, time, pendingIntent);
ArrayList<PendingIntent> intentArray = new ArrayList<PendingIntent>();
int counter=0;
for(String timer: timers){
//timers is an array of Strings in the format hh:mm
try {
String[] comps=timer.split(":");
Calendar cal=Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, Integer.valueOf(comps[0]));
cal.set(Calendar.MINUTE, Integer.valueOf(comps[1]));
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
Log.d(TAG,comps[0]+" "+comps[1]+ "Alarm Time: " + cal.getTime().toString());
PendingIntent pendingIntent = PendingIntent.getService(this, counter, myIntent,0);
am.setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(),
AlarmManager.INTERVAL_DAY,
pendingIntent);
counter++;
} catch (ParseException e) {
e.printStackTrace();
Log.d(TAG,"Time Parsing error: "+e.getMessage());
}
}
}
and this is my Alarm Receiver:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("b5.project.medibro.receivers.AlarmReceiver")) {
Toast.makeText(context, "I'm running", Toast.LENGTH_SHORT).show();
Log.d("Alarm Receiver", "Alarm is invoked. ");
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setSmallIcon(R.drawable.messenger_bubble_large_blue);
builder.setContentTitle("Time to take your medicine");
String medName = intent.getStringExtra("MedName");
String text = "Medicine name: " + medName;
builder.setContentText(text);
Notification notification = builder.build();
NotificationManagerCompat.from(context).notify(0, notification);
Toast.makeText(context, "I'm running", Toast.LENGTH_SHORT).show();
}
}
}
Manifest declaration:(its within application tags)
<receiver android:name="b5.project.medibro.receivers.AlarmReceiver"
android:enabled="true">
<intent-filter>
<action android:name="b5.project.medibro.receivers.AlarmReceiver"/>
</intent-filter>
</receiver>
I feel the above code should execute the broadcast receiver atleast once but nothing shows up in the logcat.
Can someone tell me what am I missing?
Instead of getService try getBroadcast:
PendingIntent pendingIntent = PendingIntent.getService(this, counter, myIntent,0);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, counter, myIntent,0);
Also look at http://developer.android.com/reference/android/app/PendingIntent.html#getBroadcast(android.content.Context, int, android.content.Intent, int), and figure out the flags you need, 'cause I wouldn't be surprised if only the last alarm (in the for loop) will be working.
Related
I want my alarm manager to be set for a certain time to change the phone background, but the broadcast receiver isn't doing anything. Can you help tell me why?
Scheduling alarm:
public void scheduleAlarm(Context context){
Intent intent = new Intent(context, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 18);
calendar.set(Calendar.MINUTE, 34);
am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
am.setInexactRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent );
Toast.makeText(context, "Alarm set", Toast.LENGTH_LONG).show();
}
Broadcast Receiver:
#Override
public void onReceive(Context context, Intent intent){
PendingIntent sentPI = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
GrilledCheeseLookup.getGrilledCheeseJSON(grilledCheeseUrls, context);
Toast.makeText(context, "Alarm worked", Toast.LENGTH_LONG).show();
}
Enabling in manifest:
<receiver android:name=".AlarmReceiver" android:enabled="true" />
Try creating your Intent while also specifying the packageContext, using the Intent/4 constructor (you can set the uri to null).
I'm trying to set repeating alarm between two dates. for that I set repeating alarm first using starting date and then just setting a single alarm on last date, for that i'm using other broadcast receiver on the cancel date, so that when the last day came, it got cancelled. but my alarm is not getting inside the cancelling broadcast receiver even on the last date, in short it is not getting cancelled at all.
here is my main code where i'm setting both alarms:
Log.v("setting range alarm","key range id = " + keyIds[j] + "time = " + RangeTimes[j]);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// RangeTimes[] got the starting date
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, RangeTimes[j], AlarmManager.INTERVAL_DAY,
PendingIntent.getBroadcast(this, keyIds[j], alertIntent, PendingIntent.FLAG_UPDATE_CURRENT));
Log.v("setting range alarm","key range id = " + keyIds[j] + "Cancel time = " + CancelRangeTimes[j]);
// setting the last date in alarm , cancelRangeTimes[] got the last date
Intent cancellationIntent = new Intent(this, CancelAlarmBroadcastReceiver.class);
cancellationIntent.putExtra("key", pendingIntent);
alarmManager.set(AlarmManager.RTC_WAKEUP, CancelRangeTimes[j],
PendingIntent.getBroadcast(this, keyIds[j], cancellationIntent, PendingIntent.FLAG_UPDATE_CURRENT)); // for exact repeating THIS
now this is my normal broadcast reciver for generating notifications
public void onReceive(Context context, Intent intent) {
String[] myStrings = intent.getStringArrayExtra("strings");
String pleaseText = intent.getStringExtra("text");
int count = intent.getIntExtra("count", 0);
createNotification(context, pleaseText, "trying other option", "Alert");
}
public void createNotification(Context context, String msg, String msgText, String msgAlert) {
final int _id = (int) System.currentTimeMillis(); // unique request code
PendingIntent notificationIntent = PendingIntent.getActivity(context,0, new Intent(context,MainActivity.class),0);
NotificationCompat.Builder mbuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.cast_ic_notification_play)
.setContentTitle(msg)
.setTicker(msgAlert)
.setContentText(msgText);
mbuilder.setContentIntent(notificationIntent);
mbuilder.setDefaults(NotificationCompat.DEFAULT_SOUND);
mbuilder.setAutoCancel(true); // noti dismisble when user swipe it away
NotificationManager notificationManager = (NotificationManager)
context.getSystemService((Context.NOTIFICATION_SERVICE));
notificationManager.notify(1, mbuilder.build()); // changes from 1 to _id
}
and this is my cancelling broadcast receiver
public class CancelAlarmBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
PendingIntent pendingIntent = intent.getParcelableExtra("key");
Log.v("setting the cancel","inside broadCast reciver " + pendingIntent );
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.cancel(pendingIntent);
}
}
I have looked everywhere for this solution most of the replies ask to set alarm in boot receiver.
i have implemented a boot receiver and started a service and set a alarm using set method.
Service is started fine but alarm is not setting.
please help i am stuck on that.
i can post some also if you want but boot receiver is working fine as i am also starting service in that
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sharedPref = context.getSharedPreferences(
Util.SHARED_PREF_NAME, Context.MODE_PRIVATE);
long curTime = System.currentTimeMillis();
long endTime = sharedPref.getLong(Util.END_TIME, -1);
long startTime = sharedPref.getLong(Util.START_TIME, -1);
if (curTime < endTime && startTime >= curTime) {
Intent intent1 = new Intent(context, HUD.class);
PendingIntent pintent = PendingIntent.getService(context, 1987,
intent1, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarm = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, endTime, 100, pintent);
Log.e("alaram set", endTime + " " + curTime);
}
Intent service = new Intent(context, HUD.class);
context.startService(service);
}
}
MyReceiver.java
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Manifest.xml
Service started successfully after boot
but alarm.setRepeating(AlarmManager.RTC_WAKEUP, endTime, 100, pintent);
alarm is not working.
I think i clear my question.
Plz help
Intent intent1 = new Intent(context, HUD.class);
PendingIntent pintent = PendingIntent.getService(context, 1987,
intent1, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarm = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 30);
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), 100, pending);
Try your setInexactRepeating instead of setRepeating that is more performance optimized method.
I have a Service "GroupsTaskAlarmChecker" that is called every 20 seconds by AlarmManager in onCreate of Groups.class activity this way:
int seconds = 20;
Intent myIntent = new Intent(Groups.this, GroupsTaskAlarmChecker.class);
pendingIntent = PendingIntent.getService(Groups.this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 10);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), seconds * 1000, pendingIntent);
This works perfectly. But I need to do that when device boot.
Then I know I have to make AndroidManifest like this:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name=".ReceiverBoot">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED">
<category android:name="android.intent.category.HOME">
</category></action></intent-filter>
</receiver>
and then mi broadcastReceiver like this:
public class ReceiverBoot extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
int seconds = 20;
Intent myIntent = new Intent(context, GroupsTaskAlarmChecker.class);
pendingIntent = PendingIntent.getService(context, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 10);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), seconds * 1000, pendingIntent);
}
}
but inside this onReceive I dont know how can I do the same that I did before (with intent and alarmManager to start the service each 20 seconds).
Error in this line:
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Is possible that I can't make an AlarmManager inside BroadcastReceiver?
I thank you all, I am an Android begginer and I need your help. Sorry for my english ;)
To summarize the answers and comments above: the onReceive handler receives a context which can be used to access getSystemService and ALARM_SERVICE. Sample code:
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Start periodic service.
Calendar cal = Calendar.getInstance();
Intent srvIntent = new Intent(context, MyService.class);
PendingIntent pIntent = PendingIntent.getService(context, 0, srvIntent, 0);
// Use context argument to access service
AlarmManager alarm =
(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
// Repeat every 5 seconds
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
5000, pIntent);
}
}
}
Create a new class with this code and of course change MyReceiver and MyService to the names in your implementation.
ALARM_SERVICE is neither defined in the class ReceiverBoot nor in BroadcastReceiver.
You should reference Context.ALARM_SERVICE as the argument for getSystemService(String).
Here is a little contribution, which I believe that can add a more complete vision about achieving the goal of this question.
First: configure a "receiver" inside of the AndroidManifest from your app.
<receiver
android:name=".AlarmBroadcastReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
Second: with a Class that EXTENDS the Abstract Class BroadcastReceiver, you should determine if the Intent Action was "BOOT_COMPLETED". If the condition is satisfied, you can call a method from your class which has all the construction to your Alarm.
See the following snippet bellow.
public class AlarmBroadcastReceiver extends BroadcastReceiver {
String TAG = "ALARMS";
String CLASS = this.getClass().getSimpleName() + ": ";
Context alarmContext;
#Override
public void onReceive(final Context context, Intent intent) {
Log.d(TAG, CLASS + "[START] onReceive()... ");
alarmContext = context;
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Log.d(TAG, CLASS + "BOOT_COMPLETED action has been received.");
setAlarmOnBoot();
}
Log.d(TAG, CLASS + "[END] onReceive()... ");
}
public void setAlarmOnBoot() {
Log.d(TAG, CLASS + "[START] - setAlarmOnBoot()");
final long beginAt = SystemClock.elapsedRealtime() + 60 * 1000;
final long interval = 300000; // 5 minutes
try {
AlarmManager alarm = (AlarmManager) alarmContext.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(alarmContext, AlarmBroadcastReceiver.class);
PendingIntent pIntent = PendingIntent.getService(alarmContext, 0, intent, 0);
alarm.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, beginAt, interval, pIntent);
Log.d(TAG, CLASS + "the Alarm has been configured successfully (5 minutes) of interval.");
} catch (Exception e) {
Log.d(TAG, CLASS + "an exception has ocurred while setting the Alarm...");
e.printStackTrace();
}
Log.d(TAG, CLASS + "[END] - setAlarmOnBoot()");
}
}
in your onReceive:
if ("android.intent.action.BOOT_COMPLETED".equals (intent.getAction())){
//start it again here
}
I am trying this code to popup the alarm message. Its working when launching or opening the app, but it doesn't say any popup message while outside of the app.
I am so confused, i don't know what i am doing wrong.
String alarmtime = cur.getString(cur.getColumnIndex(DBDATA.LG_ALARMTIME));
//Reminder
String[] timesplit = alarmtime.split(":");
int hour = Integer.parseInt(timesplit[0]);
int minute = Integer.parseInt(timesplit[1]);
System.out.println(hour);
System.out.println(minute);
AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, ShortTimeEntryReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
Calendar alarm = new GregorianCalendar();
alarm.setTimeInMillis(System.currentTimeMillis());
alarm.set(Calendar.HOUR_OF_DAY, hour);
alarm.set(Calendar.MINUTE, minute);
alarm.set(Calendar.SECOND, 0);
System.out.println(System.currentTimeMillis());
System.out.println(alarm.getTimeInMillis());
if (System.currentTimeMillis() > alarm.getTimeInMillis()){
alarm.setTimeInMillis(alarm.getTimeInMillis()+ 24*60*60*1000);// Okay, then tomorrow ...
alarmMgr.set(AlarmManager.RTC_WAKEUP, alarm.getTimeInMillis(),pendingIntent);
}
else
{
alarmMgr.set(AlarmManager.RTC_WAKEUP, alarm.getTimeInMillis(),pendingIntent);
}
I need to pop up the alarm message outside of the app(i.e) exactly like the alarm does.
Thanks for your help guys,
You probably need a BroadcastReceiver.
As you can read in this question : BroadcastReceiver not receiving an alarm's broadcast
You have to build the intent like this :
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(this, "CHECK_ALARM_CODE", alarmIntent, 0);
And receive the alarm like this :
public class AlarmReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm worked.", Toast.LENGTH_LONG).show();
Log.d("OK", "AlarmReceiver.onReceive");
}
}
Don't forget to register your broadcast in your manifest file.