I'm working on calendar events .
When adding events to the calendar I'm creating an alert using alarm manager
this is working fine.
I need to cancel the alert for that particular event while deleting event.
I'm setting alarm like this.
AlarmManager amgr=(AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent=new Intent(AmdAddEvent.this, RepeatingAlarmReceiver.class);
intent.putExtra("time", mAlarmTime);
PendingIntent pendingIntent=PendingIntent.getBroadcast(AmdAddEvent.this,(int) mAlarmTime,intent,PendingIntent.FLAG_CANCEL_CURRENT);
amgr.setRepeating(AlarmManager.RTC_WAKEUP, mAlarmTime,AlarmManager.INTERVAL_DAY, pendingIntent);
how to cancel alert while deleting event.
Please help me regarding this
Thanks in Advance
amgr.cancel(Pending Intent); ,
you can use this to cancel the pending alarm event.
AlaramManager Cancel
If you are coding for deleting event in another class,then you need to create an intent again with the same id(in your case,it is (int) mAlarmTime)and then you can cancel the specific alarm intent.else you can just use cancel() of alarmManager oject. Enter this lines of code where you delete the alarm event:
try
{
Intent intent=new Intent(AmdAddEvent.this, RepeatingAlarmReceiver.class);
intent.putExtra("time", mAlarmTime);
PendingIntent pendingIntent=PendingIntent.getBroadcast(AmdAddEvent.this,(int) mAlarmTime,intent,PendingIntent.FLAG_CANCEL_CURRENT);
amgr.cancel(pendingIntent);
}
catch (Exception e) {
// TODO: handle exception
}
DO NOT USE getBroadcast(), method it will not work.
Use the following code to create an alarm to create an activity:
pendingIntent = PendingIntent.getActivity(RemindingService.this, day, intent, PendingIntent.FLAG_UPDATE_CURRENT |PendingIntent.FLAG_ONE_SHOT);
Use the following code to cancel the alarm anytime:
pendingIntent = PendingIntent.getActivity(RemindingService.this, id, intent, PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_ONE_SHOT);
if(pendingIntent != null) {
alarmMgr.cancel(pendingIntent);
pendingIntent.cancel();
}
This is will tested and it is working well.
Related
I am trying to set an alarm in the alarm clock with an intent. I am using an Android One Phone (which has the unmodified OS) and have the Clock app installed (which came pre-installed) which allows setting alarm. Setting an alarm has worked in the past when I had used an AlarmManager and PendingIntent when I had to set the alarm in the background. That shows that my Clock app can respond to AlarmClock intents. But now when I am trying to send an intent from the foreground of my app, it says:
No apps can perform this action.
This is not from the stack trace, but a popup which is shown to users to choose which Clock app to choose to set the alarm (or which app to use in general for an intent)
Here's the Activity's onCreate() code where I am calling it:
public class MainActivity extends AppCompatActivity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
...
Utils.setAlarm(this, Utils.getLDT(epochTime).plusHours(8));
}
}
Here's the Utils#setAlarm function that sends the intent:
public class Utils {
public static void setAlarm(Context context, LocalDateTime alarmTimeDT) {
Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM);
intent.putExtra(AlarmClock.EXTRA_SKIP_UI, true);
intent.putExtra(AlarmClock.EXTRA_HOUR, alarmTimeDT.getHour());
intent.putExtra(AlarmClock.EXTRA_MINUTES, alarmTimeDT.getMinute());
intent.putExtra(AlarmClock.EXTRA_MESSAGE, "Good Morning");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
...
}
This is the additional code that was used in the past for the same device and same Clock app. This is for cancelling an already set alarm, but the code used to set the old alarm was similar except for the cancelling part:
//cancel old alarm
AlarmManager alarmMgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
PendingIntent alarmIntent = PendingIntent.getActivity(
this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
if (alarmIntent != null) {
alarmMgr.cancel(alarmIntent);
} else {
Log.i(TAG, "intent is null");
}
What am I doing wrong? Any help appreciated.
The below comments is just questioning and asking for more clarification on the question, which were done as asked for. So you may skip reading them
No apps can perform this action.
This happens when you don't have the required permission to set the alarm.
From AlarmClock reference:
Applications that wish to receive the ACTION_SET_ALARM and ACTION_SET_TIMER Intents should create an activity to handle the Intent that requires the permission com.android.alarm.permission.SET_ALARM.
Request the SET_ALARM permission:
<mainfest
...
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
</manifest>
My application has a login facility where the session of the logged in user is maintained by storing boolean value in the shared preference.
I want the app to logout automatically at 12:00 in the night,irrespective if the device is idle or not.So that next time the user opens the application he gets the login page and the timer is set for autologout the next night.
How do i achieve this?? Where can i set the timer for auto logout everyday??
Please help! Thanks in Advance
You can auto logout your session using the AlarmManager class. Here is the method you should call after the login.
private void callAutoLogout() {
Intent alaramIntent = new Intent(LoginActivity.this, BootCompletedIntentReceiver.class);
alaramIntent.setAction("LogOutAction");
Log.e("MethodCall","AutoLogOutCall");
alaramIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alaramIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 19);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 0);
AlarmManager alarmManager = (AlarmManager) this.getSystemService(ALARM_SERVICE);
Log.e("Logout", "Auto Logout set at..!" + calendar.getTime());
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
}
Then the BootCompletedIntentReceiver broadcast receiver will be triggered at 19.59. You can write Your action in Broadcast receiver.
public class BootCompletedIntentReceiver extends BroadcastReceiver
{
#Override
public void onReceive(final Context context, Intent intent)
{
if("LogOutAction".equals(intent.getAction())){
Log.e("LogOutAuto", intent.getAction());
Toast.makeText(context, "Logout Action", Toast.LENGTH_SHORT).show();
//Do your action
}
}
}
This is how you do it by using AlarmManager, all you need to do is to create an repeated alarm which will always trigger just moment before midnight,
just follow this,
create an broadcast receiver, register to receive an intent with action say ACTION_CLEAR_SESSION
register an pending intent of type boradcast, targetting your receiver with alarm manager
set the repeat mode as daily, and set the trigger time just before midnight
once your receive the boradcast, clear your session.
here is link just go throuh it for details
Else, simply reset everything whenever your app is opened after midnight..
I think you don't need to do the logout at exactly 12:00 in the night. When the app gets opened just check if 12 o'clock has passed and trigger the logout then and go to the login activity. This is much easier to implement and to test.
I need to create multiple notifications at multiple times. The time when the notification is supposed to appear is fetched into the event_id,etc.time for notification is set in another class.
What happens with the code below is, for a notification set at, say, 10:00, all the notifications that are set after 10:00 also appear at the same time. Please help. Only the correct notification needs to appear. Not the future ones.
for(int j=0;j<event_id.size();j++)
{
if(Integer.parseInt(event_id.get(j).toString())>newEventID&&Long.parseLong(event_time.get(j).toString())>System.currentTimeMillis())
{
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);//alarm manager
NotificationManager notificationManager=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Notification note=new Notification(R.drawable.friendi_main_logo, event_desc.get(j).toString(), System.currentTimeMillis());
Intent mainScreenIntent=new Intent(getApplicationContext(),MainScreenActivity.class);
mainScreenIntent.putExtra("UserID", user_id);
int uniqueCode=0;
uniqueCode= Integer.parseInt(event_id.get(j).toString());//unique code for each pending intent
//separate pending intent for each alarm.. one alarm manager can invoke only one PI
PendingIntent ListOfNotification=PendingIntent.getActivity(getApplicationContext(), uniqueCode,mainScreenIntent,0);
note.flags=Notification.FLAG_AUTO_CANCEL;
alarmManager.set(AlarmManager.RTC_WAKEUP, Long.valueOf(event_time.get(j).toString()), ListOfNotification);//invokes pending intent # the event_time
note.setLatestEventInfo(getApplicationContext(), "Event: "+event_title.get(j).toString(), event_group.get(j).toString()+": "+event_desc.get(j).toString(),ListOfNotification );
// Uri path=Uri.parse("android.resource://" + getPackageName() + "/alarm_sms.mp3");
// note.sound=path;
note.defaults=Notification.DEFAULT_ALL;
notificationManager.notify(EVENT_NOTIFY_ID, note);
EVENT_NOTIFY_ID++;
flag=true;
}
}
So.. what you do is..
if(Integer.parseInt(event_id.get(j).toString())>newEventID&&Long.parseLong(event_time.get(j).toString())>System.currentTimeMillis())
{
after this line..
see that the if loop is not entered again...
for example like this..
put
j=event_id.size();
this makes only one notification appear..
try using a boolean to check only the first one fires. make it true whenever you are ready to fire the 2nd one.
you are in a for loop, and you are calling notificationManager.notify(EVENT_NOTIFY_ID, note); every time, so all notifications would be fired.
boolean fire_only_one=true;
for(int j=0;j<event_id.size();j++)
{
if(Integer.parseInt(event_id.get(j).toString())>newEventID&&Long.parseLong(event_time.get(j).toString())>System.currentTimeMillis())
{
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);//alarm manager
NotificationManager notificationManager=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Notification note=new Notification(R.drawable.friendi_main_logo, event_desc.get(j).toString(), System.currentTimeMillis());
Intent mainScreenIntent=new Intent(getApplicationContext(),MainScreenActivity.class);
mainScreenIntent.putExtra("UserID", user_id);
int uniqueCode=0;
uniqueCode= Integer.parseInt(event_id.get(j).toString());//unique code for each pending intent
//separate pending intent for each alarm.. one alarm manager can invoke only one PI
PendingIntent ListOfNotification=PendingIntent.getActivity(getApplicationContext(), uniqueCode,mainScreenIntent,0);
note.flags=Notification.FLAG_AUTO_CANCEL;
alarmManager.set(AlarmManager.RTC_WAKEUP, Long.valueOf(event_time.get(j).toString()), ListOfNotification);//invokes pending intent # the event_time
note.setLatestEventInfo(getApplicationContext(), "Event: "+event_title.get(j).toString(), event_group.get(j).toString()+": "+event_desc.get(j).toString(),ListOfNotification );
// Uri path=Uri.parse("android.resource://" + getPackageName() + "/alarm_sms.mp3");
// note.sound=path;
note.defaults=Notification.DEFAULT_ALL;
if(fire_only_one){
notificationManager.notify(EVENT_NOTIFY_ID, note);
fire_only_one=false;
}
EVENT_NOTIFY_ID++;
flag=true;
}
}
fire_only_one=true;
Also You can change the logic by setting only the most relevant notification here, and when the user opens an Activity by clicking the first notification, set the second notification using ALARM manager.
I want to make a service which fire alarm manager in every 1 min interval..But
my Alarm run once(first time only).
I follow Lalit Answer
private class Receiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(getBaseContext(), "Alarm", Toast.LENGTH_LONG).show();
NetworkInfo info = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
AlarmManager mgr=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i=new Intent(context, ConnectionReceiver.class);
PendingIntent pi=PendingIntent.getBroadcast(context, 0, i, 0);
mgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1*60*1000, pi);
}
}
Juts register broadcast receiver for:
http://developer.android.com/reference/android/content/Intent.html#ACTION_TIME_TICK
Try this code in Your broadcast receiver's onReceive method
AlarmManager mgr=(AlarmManager)ctxt.getSystemService(Context.ALARM_SERVICE);
mgr.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
60000+System.currentTimeMillis(),
getPendingIntent(ctxt));
and you can get pending intent
private static PendingIntent getPendingIntent(Context ctxt) {
Intent i=new Intent(ctxt, AReceiver.class);
return(PendingIntent.getBroadcast(ctxt, 0, i, 0));
}
where AReceiver class is for start service like Notification
it is working fine in my app so i hope it helps you
I know this question already has an answer, but for others who have had the same issue but need to use AlarmManager. The reason why it only runs once is because the new PendingIntent you create does not get recreated, but rather is reusing the one before it. So in other words, the reason why your alarm only ran once was because it kept reusing it. Using the flags to refresh the intent extras if there are any should be doing the trick, but that also does not work.
A trick to use to make sure it does not reuse the PendingIntent and ultimately the Intent you provide is to use setAction() and give it some unique "Action". I did it like this:
intent.setAction("com.yourname."+System.currentTimeMillis());
As you see this makes sure its unique. Though, the above accepted answer it the best approach, if someone does not want that, they need to understand why and how to remedy that issue. Hope it helps anyone else.
I have an android activity where there is an EditText and as user types in, it calls the service on every key typed. I believe this is not efficient because more than required calls are being made. So the solution is to have some sort of pause checking there.
if (PauseOfThreeSeconds) {
// call the service here
}
How can I sense a pause and then only call the service?
Start a handler with post delayed for 3 seconds every time the key stroke is made. When ever you get a key store, cancel the runnable that is already in the queue and start a new runnable like i mentioned above.
You should schedule an alarm to start the service on each button press, but also to cancel any previously scheduled alarms so they don't go off as well:
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
long alarmWaitTime = 3000;
onButtonClicked(View v){
Intent i = new Intent(AndroidAlarmService.this, MyAlarmService.class);
PendingIntent pi = PendingIntent.getService(AndroidAlarmService.this, 0, i, 0);
// Cancel any previously set alarms
alarmManager.cancel(pi);
// set a new alarm
alarmManager.set(AlarmManager.RTC, System.getTimeInMillis() + alarmWaitTime , pi);
}