How to stop Alarm Manager? - android

I have created the start alarm as shown below
public class MyScheduleReceiver extends BroadcastReceiver {
// Restart service every 30 seconds
private static final long REPEAT_TIME = 1000 * 5;
#Override
public void onReceive(Context context, Intent intent) {
AlarmManager service = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, MyStartServiceReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(context, 0, i,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 5);
service.setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), REPEAT_TIME, pending);
I crate this for stop alarm and i call it from main activity.Manifest i think is ok...Work repeat but no stop!!!
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setup);
sendBroadcast(new Intent(this,MyScheduleReceiver.class));
}
public void StopRepeat(View view) {
sendBroadcast(new Intent(this,MyStopReceiver.class));
}
public class MyStartServiceReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Repeat service!.",
Toast.LENGTH_LONG).show();
}
public class MyStopReceiver extends BroadcastReceiver {
// Restart service every 30 seconds
private static final long REPEAT_TIME = 1000 * 5;
#Override
public void onReceive(Context context, Intent intent) {
AlarmManager service = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent istop = new Intent(context, MyStartServiceReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(context, 0, istop,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 5);
service.cancel(pending);
But the service is not stopping. What might be the issue?Thanks.

The simplest option is to restart your device. (If you created a BOOT_COMPLETED listener just remove it for now.)
You can also cancel an alarm by passing the PendingIntent you used to create the alarm to AlarmManager#cancel(). You have already written the code to do this, but do you have a Button with the XML attribute android:onClick="StopRepeat" in setup.xml? Did you click it?
Solution
We eventually discovered you had a mistake in your Manifest file, so MyStopServiceReceiver was never called...

Related

Alarm Manager does not work as expected when scheduling task

I'm currently working with Android Alarm Manager and found a working example. But it does not work properly in my situation. Let me explain. Basically my goal is to execute a method from the MainActivity each 5 mins. For this purpose I use Alarm Manager to schedule that task.
Basically this is the working stuff:
AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.sendBroadcast(new Intent("SERVICE_TEMPORARY_STOPPED"));
}
}
MainActivity.java
public class MainActivity extends Activity{
private PendingIntent pendingIntent;
private AlarmManager manager;
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "I'm running", Toast.LENGTH_SHORT).show();
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
registerReceiver(broadcastReceiver, new IntentFilter("SERVICE_TEMPORARY_STOPPED"));
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startAlarm();
}
});
}
public void startAlarm() {
manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
int interval = 300000;
manager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
Log.d(TAG, "Alarm Set");
}
}
Everything is good. "I'm running" Toast is executed every 300000 ms (5 mins). The AlarmReceiver class send a broadcast to my main Activity with the message "SERVICE_TEMPORARY_STOPPED". I already registered that message in my MainActivity via registerReceiver(broadcastReceiver, new IntentFilter("SERVICE_TEMPORARY_STOPPED"));. But, when I add another method, let's say stopAlarm() in the broadcastReceiver, which is going to stop the alarm after 5 mins, the time interval (5 mins) is not applied anymore. In something like 10 secs, it calls the Broadcast Receiver and stop the alarm. And this is the issue. Take a look at the stop() method and how I call it on the broadcastReceiver:
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "I'm running", Toast.LENGTH_SHORT).show();
stopAlarm();
}
};
public void stopAlarm() {
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
manager.cancel(pendingIntent);
Log.d(TAG, "Alarm Cancelled");
}
Any clue?
AlarmManager.setRepeating doesn't work properly on different android versions.
Try setExact. It won't repeat but you can achieve repeating functionality as mentioned below:
Updated AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.sendBroadcast(new Intent("SERVICE_TEMPORARY_STOPPED"));
long repeatCount = PreferenceManager.getDefaultSharedPreferences(context).getLong("REPEAT_COUNT", 0L);
repeatCount++;
PreferenceManager.getDefaultSharedPreferences (context).edit().putLong("REPEAT_COUNT", repeatCount).apply()
AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
manager.setExact(AlarmManager.RTC_WAKEUP, (repeatCount *System.currentTimeMillis()),pendingIntent);
}
}
Here we maintain a repeatCount & variable (preference based) and increment it in your AlarmReceiver & schedule alarm again by calculating nextAlarmTime using repeatCount * System.currentTimeMillis();

Why Background Service stops working when app is closed?

I am trying to create a background service that will be called every ten minutes, perform a task and this should not be killed when the application is closed.
The following is the code snippet:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location_service);
Intent intent = new Intent(this, AlarmReceiverLifeLog.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
alarms.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 10 * 60 * 1000, pendingIntent);
}
In onCreate, it will call the AlarmReceiverLifeLog class every ten minutes. The following is the code for AlarmReceiverLifeLog class:
public class AlarmReceiverLifeLog extends BroadcastReceiver {
static Context context;
#Override
public void onReceive(Context context, Intent intent) {
Intent ll24Service = new Intent(context, LifeLogService.class);
context.startService(ll24Service);
}
}
public class LifeLogService extends Service {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onDestroy() {
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartService = new Intent(getApplicationContext(), this.getClass());
restartService.setPackage(getPackageName());
PendingIntent restartServicePI = PendingIntent.getService(getApplicationContext(), 1, restartService, PendingIntent.FLAG_ONE_SHOT);
Calendar calendar = Calendar.getInstance();
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, calendar.getTimeInMillis() + 100, restartServicePI);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
I am not able to figure out what I have missed. When I close the app the background services is getting killed.
Can anyone suggest anything regarding this?
when the app is closed the service get closed also because they are in a one thread, so the service should be on another thread in order fot it not to be closed, look into that and look into keeping the service alive with alarm manager here an example http://www.vogella.com/articles/AndroidServices/article.html this way your service won't be shown in notification.

Cancelling an alarm that starts within a class that launches when the reboot is complete

Here is my class which launches and sets an alarm when the phone is rebooted.
public class NotifStart extends BroadcastReceiver
{
private static AlarmNotif reAlarm = new AlarmNotif();
#Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
{
reAlarm.SetAlarm(context.getApplicationContext());
}
}
}
and here's my alarm's receiver class:
public class AlarmNotifReceiver extends BroadcastReceiver {
PendingIntent pi;
#Override
public void onReceive(Context context, Intent intent)
{
//stuff
}
public void SetAlarm(Context context)
{
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, AlarmNotifReceiver.class);
pi = PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 10*1000, pi); // Millisec * Second
}
public void CancelAlarm(Context context)
{
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.cancel(pi);
}
}
Now, if I use SetAlarm() as the phone is open I am able to use CancelAlarm() and actually cancel it. But whenever I reboot the phone and set the alarm by using the above class NotifStart I am unable to cancel it. I tried to use the cancel method from within the NotifStart but since I can't really give the context of a non-activity class as onReceive it just doesn't work.
From the docs:
A BroadcastReceiver object is only valid for the duration of the call to onReceive(Context, Intent). Once your code returns from this function, the system considers the object to be finished and no longer active.
So when you call your CancelAlarm your pending intent might be null or not equal to pending intent used for setting alarm.
In CancelAlarm(Context context) your pi might be null, check and re-create it with the same requestCode before performing cancel.
public void CancelAlarm(Context context)
{
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, AlarmNotifReceiver.class);
pi = PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
am.cancel(pi);
}

Android: setting new Alarm from onReceive method

I have a collection of reminders in my database(sort by time). When my application starts I call setAlarm. I need to add code in onReceive method in order to do these tasks:
Get first reminder from my database
Get the delay associated to the reminder
Schedule a new Alarm for getting the next reminder.
I created a simple BroadcastReceiver class:
public class AlarmReceiver extends BroadcastReceiver{
private static final String DEBUG_TAG= "AlarmReceiver";
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
Log.d(DEBUG_TAG,"ALARM!!!");
// --mycode--
}
}
and the Activity class:
public class AlarmActivity extends Activity {
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
context = getApplicationContext();
}
public void setAlarm(View v){
Intent intent = new Intent(this,AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+ Delay,pendingIntent);
Log.i("SETTER","Alarm started");
}
public void stopAlarm(View v){
Intent intent = new Intent(this,AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
pendingIntent.cancel();
}
}
Now, I would that in the --mycode-- section new Delay is taken (if exists) from database and new Alarm is setted with this new Delay.
How can I set a new AlarmManager from onReceive method?
You can get AlarmManager in the broadcast receiver by accessing it from the context
AlarmManager alarmManager = (AlarmManager)arg0.getSystemService(Context.ALARM_SERVICE);
where arg0 is your context variable

Android AlarmManager not Triggering

I'm just trying to get a simple test app working with AlarmManager.
public class TestActivity extends Activity {
private static final int PERIOD = 1000;
private AlarmManager alarmManager;
private PendingIntent pendingIntent;
#Override
public void onCreate(Bundle savedInstanceState) {
Log.v("TextActivity", "WHY NOT!");
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, TestReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, intent,
PendingIntent.FLAG_CANCEL_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), PERIOD, pendingIntent);
Log.v("TestActivity", "Whee!");
}
}
public class TestReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.v("TestReceiver", "Got Here");
}
}
I have tried this on both a hardware phone and the emulator and I am not seeing the messages received. Am I missing something obvious? I am relatively new to Android development.
Did you register your receiver in AndroidManifest.xml? Also period is milliseconds, so that alarm will trigger every second, is this really what you want?

Categories

Resources