How to stop an android repeating alarm from a notification action - android

I'am trying to find a way to use an NotificationCompat.Builder.addAction(...) to call some code to stop a repeating alarm without starting an activity... but as i understood so far the only thing I can do with this is start intents with Activities.
There's any way I can stop the alarm without leaving the notification?

You can add request to alarm manager by calling set() function with PendingIntent as parameter. You just need to call cancel() with same PendingIntent, in order to stop it; though I note very clear about your notification question.

Related

Can we startForegroundServie from an exact alarm's receiver in the background?

In one of the exemptions of the "cannot start foreground service from background" restriction, the doc mentions:
Your app invokes an exact alarm to complete an action that the user
requests.
Does this mean that the usage scenario below can work?
Use AlarmManager.setAlarmClock to schedule an exact alarm to trigger at time A. The alarm carries a pendingIntent that targets a registered broadcast receiver.
Time A hits, the receiver gets the intent.
In the receiver OnCreate method, we attempt to startForegroundServicewhich involves displaying a sticky notification and playing custom music with MediaPlayer.
I have implemented and tested this and it appears to be working, so I assume this is a valid use case.

CountDownTimer service

Im trying to make a countdown timer run in the background of my activity, it needs to run constantly until it finishes, but not sure how to make it work with a service. I also need to update the display on my main activity
Uh, not all services run 100% of the time. Nothing is a battery drain unless it's executing at 100%. If you look at the actual battery consumption of an Android device, you'll see that the largest percentage comes from the screen. The next comes from radios. Running a process costs very little.
You can use an IntentService to fire off an alarm at regular intervals. The service can send intents to itself. Have one intent action to start the service, and one to turn off the alarm. Make a third action for resetting the alarm.
To start the service, send a "start" intent to the IntentService using startService(intent). This should trigger a method that creates an intent with action "cycle", puts the intent in a PendingIntent, and schedules a repeating alarm with AlarmManager.setRepeating().
After the interval that you set for the alarm, the AlarmManager will take the "cycle" intent out of the PendingIntent and send it back to your service. Your service should handle "cycle" by rebuilding the PendingIntent and restarting the alarm. This goes on indefinitely. You can put anything else you want to do when the alarm goes off in the handling for the "cycle" action.
When you want the alarm to stop, send the "stop" intent. In response, your service should cancel the alarm by reconstructing the PendingIntent and then calling AlarmManager.cancel().
Notes: The main entry point for an IntentService is onHandleIntent(). You call everything else from there. When that method finishes, the service goes inactive until it receives another intent. The only place you can "see" it is in cached processes. Once you stop the alarm, the system will eventually figure out that the service isn't being used, and garbage-collect it.
Services are the way to do background work. I suppose you can run some AsyncTask or a thread, but you still want to run them in a Service, otherwise you've linked them to something that's running in the foreground. If the task doesn't need to interact with the user, particularly if it can work asynchronously to your activity, then use a service.

Should I use PendingIntent.getService() or getBroadcast with AlarmManager?

My app needs to grab some data from the web at a specific time each day. So I use an AlarmManager to schedule the task and that works ok.
But when looking at various examples there seems to be two ways to deal with the AlarmManager when it comes to the pending intent.
One uses PendingIntent.getBroadcast() to call a broadcast receiver when the alarm goes off and inside that receiver the service to do the real work is started.
Another approach is to use PendingIntent.getService() and call the service directly when that alarm goes off.
Can someone explain to me the difference between the two approaches so I can decide on which one to rely?
EDIT: One more question is where to acquire the wake lock when using getService()?
For example, when using a BroadcastReceiver I have the following line in onReceive():
WakeReminderIntentService.acquireStaticLock(context);
How should I acquire the wake lock if I instead call the service directly like:
PendingIntent pi = PendingIntent.getService(this, 0, new Intent(this, OnAlarmReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
Should I simply acquire it from within the service instead?
One uses PendingIntent.getBroadcast() to call a broadcast receiver when the alarm goes off and inside that receiver the service to do the real work is started.
it has one more step in starting service than
Another approach is to use PendingIntent.getService() and call the service directly when that alarm goes off.
then you should use the second approach as it is reducing your one step in execution..
Reading your edit I presume you found out yourself: If you want to make sure that your service is started when using AlarmManager, you better take the detour of first sending to a receiver and acquiring a wake lock there.
Otherwise it is possible that the phone will sleep before the requested service is launched.
That's what the javadoc of AlarmManager says and I also read it in post by Google engineer.
So now for your edit: When to acquire the lock?
The whole point of using the receiver is to acquire the lock within the onReceive() method of the receiver, because Android will not fall asleep during the execution of this method.
For an example see this question.

Controlling Alarm from 2 diff applications - Android

I need help in my android app development.
It goes something like this,
I will be having two separate applications (2 projects). In one application, i have to start a repeating alarm and in the other application i have to cancel the same alarm that was started in the first application.
The Android documentation says, the same pending intent and the intent object that was used to start the alarm
should be used the cancel the alarm.
So in this scenario, the pending intent and the intent object that was used to start the alarm will belong to application1 so i cannot used the same objects in application2
How do I proceed?
In summary -
The problem is, I need to start a repeating alarm from one application and i have to cancel the same alarm from another application.
Can this be done. If so, How?
Thanks in advance.
ifreeman
It is not that straightforward. Only original activity can cancel the alarm.
So I think you can configure a custom broadcast. When the second activity needs to cancel an alarm it will send this broadcast. The first activity will be listening to the broadcast and cancel the appropriate alarm on receiving it.
I guess you can do. Alarms are considered as same if intents passed to them via pending intent are same. filterEquals method of Intent class defins if intents are same or not. If intents are same then alarms are same so u can cancel that alarm. Check once.

Cancel AlarmManager which was set in Service

folks! I have Service, which checks in onStartCommand() whether auto update was set in user preferences and sets AlarmManager update time if needed. So, I want to acomplish following: consider that AlarmManager is alread set, and user turns auto update off, I want to cancel the alarm. The only idea I have is to broadcast custom intent to service that preferences were changed. Is there another way to do it?
UPD or I just need to call stopService()?
A broadcast is definitely the best way to communicate between an activity/widget and a service.

Categories

Resources