Trying to create multiple Alarms using unique PendingIntent . However I am having trouble with this,
From MainActivity I press a button to set an Alarm, and the code for that is:
public void alarmSet(View view)
{
int idTime = (int) System.currentTimeMillis();
Intent intent = new Intent(MainActivity.this, AddAlarm.class);
intent.putExtra("pendInt",idTime);
startActivity(new Intent(MainActivity.this, AddAlarm.class));
}
Taking System time as unique id I am passing the value to the other activity from which I call the Broadcast to initiate alarm. Code for this Activity is:
Intent receive = getIntent();
pen = receive.getIntExtra("pendInt",0);
And here is the method in which I set the alarm.
private void setAlarm(Calendar targetCal)
{
Intent alarmintent = new Intent(AddAlarm.this, AlarmReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(AddAlarm.this, pen, alarmintent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, targetCal.getTimeInMillis(), sender);
}
This works for single alarms , however it doesn't generate multiple alarms. What might be the possible reason? Any help will be appreciated. Do I need to post the Broadcast class as well ?
you are making Intent and putting extra but passing another Intent to startActivity()
just replace this
startActivity(new Intent(MainActivity.this, AddAlarm.class));
to this
startActivity(intent );
Related
I set an alarm from activity A then in activity B I can delete and update the alarm set in activity A. Updating of alarm is working but delete doesn't, I've already tried some answer from here but nothing seems to work.
I set my alarms like this.
public void Alarms() {
for(eventlist_model model:arrayList)
{
int id=model.getEvent_id();
String type=model.getEvent_type();
String date=model.getEvent_date();
String time=model.getEvent_time();
String note=model.getEvent_note();
SimpleDateFormat format= new SimpleDateFormat("yyyy-MM-dd HH:mm");
try{
String sched=date+" "+time;
Date newSched=format.parse(sched);
Calendar calendar1 = Calendar.getInstance();
calendar1.setTime(newSched);
if (calendar1.before(calendar))
calendar1.add(Calendar.DATE, 1);
Intent intent = new Intent(this, events_receiver.class).setAction("Dog_alarm");
intent.putExtra("type", type);
intent.putExtra("note", note);
intent.putExtra("id", id);
PendingIntent dog1 = PendingIntent.getBroadcast(this, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
final AlarmManager alarm1 = (AlarmManager) getSystemService(ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= 19) {
alarm1.setExact(AlarmManager.RTC_WAKEUP, calendar1.getTimeInMillis(), dog1);
} else {
alarm1.set(AlarmManager.RTC_WAKEUP, calendar1.getTimeInMillis(), dog1);
}
}catch (Exception e)
{
e.printStackTrace();
}
}
}
then in activity B I use this to cancel the alarm
public void cancelTask()
{ int id=Integer.valueOf(eventid);
Intent intent = new Intent(update_task.this, events_receiver.class);
AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent task = PendingIntent.getBroadcast(this, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarm.cancel(task);
}
But it doesn't work and Im stuck here. Can anyone help me in this?
According to documentation of cancel method of AlarmManager:
void cancel (PendingIntent operation)
Remove any alarms with a matching Intent. Any alarm, of any type,
whose Intent matches this one (as defined by filterEquals(Intent)),
will be canceled.
It means if intentA detected to be equal withintentB, using filterEqauls Method, i.e. intentA.filterEquals(intentB)==true, then intentB in alarmanger can be used to cancel intentA which already set inside alarmManager.
filterEquals documentation notices:
boolean filterEquals (Intent other)
Determine if two intents are the same for the purposes of intent
resolution (filtering). That is, if their action, data, type, class,
and categories are the same. This does not compare any extra data
included in the intents.
It means it filterEquals does not care to extras inside intents to compare them but other paramters like Action should be exactly the same.
In your case, you've missed to call setAction in cancellation intent.
So you should change your cancelTask method like this:
public void cancelTask()
{ int id=Integer.valueOf(eventid);
Intent intent = new Intent(update_task.this, events_receiver.class);
intent.setAction("Dog_alarm");//<--- this is missed
AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent task = PendingIntent.getBroadcast(this, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarm.cancel(task);
}
I have two pending Intent to use with Alarm Manager one is:
Intent i = new Intent(context, TriggerAlarm.class);
PendingIntent pi =PendingIntent.getBroadcast(context,0,i,PendingIntent.FLAG_CANCEL_CURRENT);
and the other is:
Intent i = new Intent(context, TriggerNotification.class);
PendingIntent pi = PendingIntent.getBroadcast(context,0, i,PendingIntent.FLAG_CANCEL_CURRENT);
I use these two in different methods in my application
my question is:
Are these pendingIntents differnt from each other?? because the intents are different but the Ids are same
If I set alarm manager for each of these pending intent do both of them trigger or one replace another?
So the easy way is test it directly by yourself.
I have tested it on my computer and here is what i got:
Are these pendingIntents different from each other?? because the intents are different but the Ids are same
-Yes they are different each other although the Ids are same
If I set alarm manager for each of these pending intent do both of them trigger or one replace another?
-Both of them will be triggered
Here are my code for test, you can copy and try it by yourself
Copy this method to your activity, and call it
private void setAlarmManager() {
Log.v("AlarmManager", "Configuring AlarmManager...");
Intent startIntent1 = new Intent(context, AlarmReceiverFirst.class);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 0, startIntent1, PendingIntent.FLAG_CANCEL_CURRENT);
Intent startIntent2 = new Intent(context, AlarmReceiverSecond.class);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 0, startIntent2, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 20);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Log.v("AlarmManager", "Starting AlarmManager for >= KITKAT version");
alarm.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent1);
alarm.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent2);
} else {
Log.v("AlarmManager", "Starting AlarmManager for < KITKAT version");
alarm.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent1);
alarm.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent2);
}
Log.v("AlarmManager", "AlarmManager has been started");
}
Create your first receiver class
public class AlarmReceiverFirst extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.v(this.getClass().getSimpleName(), "first alarm receiver is called");
}
}
Create your second receiver class
public class AlarmReceiverSecond extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.v(this.getClass().getSimpleName(), "second alarm receiver is called");
}
}
Register those receivers to your manifest
<receiver android:name=".AlarmReceiverFirst" />
<receiver android:name=".AlarmReceiverSecond" />
Not to be confused, what you called Id here is called request code. It is used for cancelling the pending intent.
Intents are just the action PendingIntent is bound to execute once it triggers. But this triggering criteria are entirely depending on PendingIntent itself and RequestCode is playing here a pretty good role to uniquely identify, manage and trigger PendingIntent.
Therefore, no matter what the Intent is, if the requestCode is repeated then the latter PendingIntent will trigger. If you need to trigger multiple PendingIntents, the requestCode must be different from each other.
You can have same name of intents but with different ids like following,
Intent i = new Intent(context, TriggerAlarm.class);
PendingIntent pi =PendingIntent.getBroadcast(context,System.currentTimeMillis(),i,PendingIntent.FLAG_CANCEL_CURRENT);
And
Intent i = new Intent(context, TriggerNotification.class);
PendingIntent pi = PendingIntent.getBroadcast(context,System.currentTimeMillis(), i,PendingIntent.FLAG_CANCEL_CURRENT);
This way both the intents would be distinguished differently from each other and will get triggered.You can have any unique id instead of System.currentTimeMillis()
I am calling broadcast receiver from service through this method.
Intent intent = new Intent(NotifyService.this, AlarmReciever.class);
intent.putExtra("TIME",ttime);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 34324243, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,timee,pendingIntent);
In Broadcastreceiver page I am receiveing through this method.
Bundle b = in.getExtras();
date = b.getString("TIME");
Problem is In Broadcastreceiver page I am getting null value.
My Question is :-
How to pass data from service to broadcastreceiver ?
In your main activity start your service as
i = new Intent(this, SimpleService.class);
startService(i);
registerReceiver(broadcastReceiver, new IntentFilter(SimpleService.BROADCAST_ACTION));
use send broadcast to send any value from service class to mainactiviy class as
intent.putExtra("textval", s);
sendBroadcast(intent);
and then in your main activity class receive it as
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//do your coding here using intent
}
};
OK i assume the "ttime" is a bundle ( from the code your wrote it seems to make sense)
Try and recieve the data like this
Bundle b= in.getBundleExtra("TIME");
In case the "tttime" is of other format say a String or Int you can get the data in onReceive of Broadcastreceiverlike this
String :
in.getStringExtra("TIME");
Integer :
in.getIntExtra("TIME", -1) // -1 is default value which will be return incase no matching integer found with the key "TIME" in intent "in"
For full details and how to get data from intent of different type refer to android documentation
you missed to do like this:-
Intent intent = new Intent(NotifyService.this, AlarmReciever.class);
sendBroadcast(intent);
You can call pendingIntent Like this:-
PendingIntent operation = PendingIntent.getBroadcast(Service.this,
0, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(),5* 60 * 1000, operation);
If you are passing any time data to broadcast class,then you can receive that data in receiver class as
String mTime = NotifyService.time;
Try this. Inform me also.
In my android i app i can alarm functionality and as well logout functionality. After setting my alarm time i am exiting the app by clicking the logout button.
I am using
ExitActivity.this.finish();
Intent intent1 = new Intent(ExitActivity.this,PinActivity.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent1);
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
this code to exit the app,which goes to home pin screen and after that it launches the home screen. This is because when i am coming back to my app it launches the pinscreen. Alarm working exactly what i want but while alarm popup message it has the pinactivity in the background(which i don't want). I wan't to get rid out of the pin activity in the background.
This is my receiver class?
public class ShortTimeEntryReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"Alarm Working", Toast.LENGTH_SHORT).show();
try {
Bundle bundle = intent.getExtras();
String message = bundle.getString("alarm_message");
Intent newIntent = new Intent(context, ReminderPopupMessage.class);
newIntent.putExtra("alarm_message", 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();
}
}
How do i do that?
Thanks for your help guys..
You should use Alarm Manager to set alarms in Android. The alarm manager holds your alarm and fire an pending intent on alarm time.
First create a pending intent like this :
pendingIntent = PendingIntent.getService(CONTEXT, ALARM_ID, INTENT_TO_LAUNCH, 0);
Then use this pending intent to set an Alarm like this :
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, ALARM_TIME, pendingIntent);
This will start the pending intent at given time.
To remove an alarm you have to recreate the same Pending Intent with same ALARM_ID :
alarmManager.cancel(pendingIntent);
First create a pending intent like this :
pendingIntent = PendingIntent.getService(context, alarm_id, Pass your data with intent, PendingIntent.FLAG_UPDATE_CURRENT);
Set an Alarm like this :
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//19 4.4and above api level
am.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis() + AlarmManager.INTERVAL_DAY, sender);
} else {
//below 19 4.4
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis() + AlarmManager.INTERVAL_DAY, sender);
}
This will start the pending intent at given time.
To remove an alarm you have to Use the same Pending Intent with same ALARM_ID:
am.cancel(pendingIntent);
Now You need to create One Service to catch your Alarm.
first of all , i would like to apologize for my English its bad
all of alarm that i create by this class
Intent intent = new Intent(SETALARM.this, ALARMRECEIVER.class);
intent.putExtra("pk", pk);
sender = PendingIntent.getBroadcast(this, pk, intent, PendingIntent.FLAG_CANCEL_CURRENT);
am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),60000, sender);
were cleared when device is shut off
what should i do to restore all of alarm back
thank you very much for your help
edit
here is receiver class
#Override
public void onReceive(Context context, Intent intent) {
WakeLocker.acquire(context);
pk = Integer.parseInt(intent.getExtras().get("pk").toString());
Intent intent2 = new Intent(context,ALERT.class);
intent2.putExtra("pk", pk);
intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent2);
WakeLocker.release();
}}
If you mean that you lose the alarms when the device is turned off then this issue has been addressed well here
https://stackoverflow.com/a/5439320/374866