Why isn't my AlarmManager working? - android

I am trying to make an alarm that triggers an event some number of seconds from now, one time, from within a DialogFragment.
Here is the relevant code, I put in onCreate():
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent i) {
Toast.makeText(c, "Rise and Shine!", Toast.LENGTH_LONG).show();
}
};
getActivity().registerReceiver(broadcastReceiver, new IntentFilter(ALARM_MANAGER_TAG) );
pendingIntent = PendingIntent.getBroadcast(getActivity(), 0, new Intent(ALARM_MANAGER_TAG), 0 );
alarmManager = (AlarmManager)(getActivity().getSystemService( Context.ALARM_SERVICE ));
And then when I press the start button:
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, timestampEnd, pendingIntent);
In this case timestampEnd = System.currentTimeMillis() + 10 * 1000;, 10 seconds.
And then I have overridden destroy:
#Override
public void onDestroy() {
alarmManager.cancel(pendingIntent);
getActivity().unregisterReceiver(broadcastReceiver);
super.onDestroy();
}
And yet, nothing happens for some reason.

You're passing AlarmManager.ELAPSED_REALTIME_WAKEUP, which means the AlarmManager is going to use SystemClock.elapsedRealtime() when checking timestamps. Since you're passing something calculated off of System.currentTimeMillis(), you are going to have to wait about 47 years before the alarm fires.
Either change your first argument to AlarmManager.RTC_WAKEUP or change your timestamp to be calculated off of SystemClock.elapsedRealtime().

Related

Do action after some time when your app is not active / running

I have some sensitive data that I load on the device in my application. And it can be reused between sessions / multiple uses of the app and be cleared when not in use / open / active.
So the app is not active / running. There is a notification showing that the sensitive information is still in memory.
But I want to give the user an option of clearing this data after a set amount of time.
So my question is how do I run some code after a set number of minutes?
You can schedule an alarm using the AlarmManager and run your code from the BroadcastReceiver/Service. The alarm will trigger weather your app is dead or alive. (If it's dead it will be awaken)
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(), AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);
You can use this method to register a one time alarm. So if you want the alarm to trigger in 5 mins, the delayMillis value should be 5 * 1000 * 60
void registerOneTimeAlarm(PendingIntent pendingIntent, long delayMillis) {
int SDK_INT = Build.VERSION.SDK_INT;
long timeInMillis = System.currentTimeMillis() + delayMillis;
if (SDK_INT < Build.VERSION_CODES.KITKAT) {
alarmManager.set(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent);
} else if (SDK_INT < Build.VERSION_CODES.M) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent);
} else {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent);
}
}
Let's say you will use a receiver, it will look like this:
public class AlarmReceiver
extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Your code here
}
}
And don't forget to add it in the Manifest:
<receiver android:name="your.package.AlarmReceiver"/>
IMPORTANT
Registered alarms are cleared when the device reboots, you need to re-register the alarm after the device boots. (If this is what you really need)
You can try this
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//Actions to be performed
}
}, TIME_OF_DELAY);

how can I set repeating alarm every 5 second to show message

here is my code in application class inside oncreate method: But I can't see any message from my app. Can anyone help me to do this?
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
public void startAlarm() {
manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
int interval = 5000;
manager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
Toast.makeText(this, "Alarm Set", Toast.LENGTH_SHORT).show();
}
And on the broadcast receiver class I have the following code
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent arg1) {
// For our recurring task, we'll just display a message
Toast.makeText(arg0, "I'm running", Toast.LENGTH_SHORT).show();
}
}
Edited answer:
Use setInexactRepeating() instead of setRepeating(). setRepeating only takes set intervals with the shortest being INTERVAL_FIFTEEN_MINUTES. setInexactRepeating() is the only way to set a repeating interval as short as 1000ms, or 5000ms in your case.
Change:
manager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
to
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
If you are not getting the exact 5 second delay that you need, you will need to use a Handler. Any type of alarm with a 5 second delay will not work properly because as of Android 5.x basically all repeating alarms are inexact to save battery life.
I have modified your code to use a Handler:
startAlarm();
public void startAlarm() {
final Handler h = new Handler();
final int delay = 5000; //milliseconds
h.postDelayed(new Runnable(){
public void run(){
//do something
Intent alarmIntent = new Intent(getApplicationContext(), AlarmReceiver.class);
sendBroadcast(alarmIntent);
h.postDelayed(this, delay);
}
}, delay);
}
That alarm method will work with your current BroadcastReceiver and do an actual 5 second delay.

Stop the background service after particular time in android

Hi i need to stop the Background service which is already started after particular time.I will get the duration from server for when to stop the service.I have tried the Alarm Manager in android.
Calendar cal = Calendar.getInstance();
Intent intent = new Intent(context, MyService.class);
PendingIntent pintent = PendingIntent.getService(context, 0, intent, 0);
AlarmManager alarm = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
// Start every 30 seconds
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 60*1000, pintent);
Log.e(TAG, "Service started in Activity");
This above code is starting the service after every one minute.But i dont want to start the service.I need to stop the service after a minute.How to do that.Is that possible to do with Alarm Manager.Please guide me.
Try that:
add parameter to your pendingIntent
Intent intent = new Intent(context, MyService.class);
intent.putExtra("param_name", "end");
PendingIntent pintent = PendingIntent.getService(context, 0, intent, 0);
Override onStartCommand() method in your Service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try{
String parameter = intent.getStringExtra("param_name");
if(parameter.equals("end")){
stopSelf();
}
}catch(Exception ex){
}
}
Also you can try to use Handler in your service:
Handler variable:
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1: {
stopSelf();
}break;
}
}
}
Delayed task:
handler.sendEmptyMessageDelayed(1, 60 * 1000);
Create the timer task to stop the service and assign the delay time which you are getting from your server
Timer timer = new Timer ();
TimerTask hourlyTask = new TimerTask () {
#Override
public void run () {
// your code here to stop the service ...
}
};
// schedule the task to run assign the time (DelayTime) which you are getting from server
timer.schedule (hourlyTask, DelayTime);
So what is the particular time.
You can do 1 thing make note of the starting time of the service. and if you want to stop the service after a specified duration or the specific time get the system current time compare it with that time if it match's stop the service. this should resolve the problem.
Tell me if it works for you..
======>
Just Follow the steps provided steps below:
Use sharedprefrence to save the start time of the service.
If your not familiar to shearedprefrence URL:http://examples.javacodegeeks.com/android/core/content/android-sharedpreferences-example/
Then in the service onStart method get the system current time if it
matches the time stop the service.
You have to create an broadcast receiver:
Calendar cal = Calendar.getInstance(); // this will return current time
// if you want to trigger after 1 minute then add into calender object
cal.add(Calendar.MINUTE, 1);
Intent intentAlarm = new Intent(this, AlarmReciever.class);
intentAlarm.setAction("My_Action");
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
MainActivity.this, REQUEST_CODE, intentAlarm,
PendingIntent.FLAG_UPDATE_CURRENT);
// set the alarm for particular time
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
AlarmReciever .java
public class AlarmReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// call method to stop service
}
}
Also declare this AlarmReceiver class in menifest file
<receiver android:name=".AlarmReciever" >
</receiver>
> here i used the countdowntime for 30second
after 30second call stopself() method it will stop your
services..u can also do what ever u want on finsih you can also pass a
notification to the user....
new CountDownTimer(30000, 1000) {
#Override
public void onTick(long l) {
}
#Override
public void onFinish() {
//r u can also pass a notification
stopSelf();
}
}.start();

How to cancel and set AlarmManager at the same time

What I am doing at the moment is, using AlarmManager.SetAlarm(context) to enable and AlarmManager.CancelAlarm(context) to cancel it. I am using it with an IntentService.
What I want to do is cancel the alarm from triggered IntentService and then set it again such as:
#Override
protected void onHandleIntent(Intent intent) {
FooAlarmManager foo = new FooAlarmManager();
foo.CancelAlarm(FooClass.this);
//Do some stuff
foo.SetAlarm(FooClass.this);
}
Why I am doing this? Because within FooAlarmManager I am getting the time from a static class such as:
public void SetAlarm(Context context) {
Integer minutes = StaticValuePass.getMins();
AlarmManager am = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, FooAlarmManager.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setInexactRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), 1000 * minutes*60, pi);
}
And I am setting the value of time from onHandleIntent(). So basically I am doing some check within onHandleIntent() and determining when should be the next alarm.
Unfortunetely, my code above doesn't work, the reason is when you use setAlarm() it actually invokes onHandleIntent() immediately.
So I have two questions in this case,
1) Can I prevent setAlarm() to invoke onHandleIntent() when it is firstly created?
2) (Assuming the above doesn't work) How can I change the alarm interval time?
The second parameter, currently System.currentTimeMillis(), is the time at which you want the repeating alarm to first go off. So setting it to the current time will trigger the alarm immediately. Setting it to System.currentTimeMillis() + (1000 * minutes * 60) should fix your problem.
Please refer to the documentation: https://developer.android.com/reference/android/app/AlarmManager.html#setInexactRepeating(int,+long,+long,+android.app.PendingIntent)

Alarm manager triggered immediately

Hi I am currently working with AlarmManager. I have written a code given below. As per code the AlarmManager should be triggered after 10 Sec, but here in my code the alarm manager triggers immediately. Please help.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
int alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP;
long timeOrLengthofWait = 10000;
Intent intentToFire = new Intent(this, AlarmReciever.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0, intentToFire, 0);
alarmManager.set(alarmType, timeOrLengthofWait, alarmIntent);
}
}
And My AlarmReciever Class
public class AlarmReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String phoneNumberReciever="5556";
String message="Alarm Triggered";
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumberReciever, null, message, null, null);
Toast.makeText(context," A message has been sent", Toast.LENGTH_LONG).show();
Log.d("Alarm ", "Alarm Has been triggered and sms send");
}
}
I have Already added required permissions in manifest.
You are using an alarm type of ELAPSED_REALTIME_WAKEUP. That means that the second parameter to set() must be the number of milliseconds from now, where now is expressed as SystemClock.elapsedRealtime().
If your goal is to have this occur 10000 milliseconds from the time you make the set() call, that set() call should be:
alarmManager.set(alarmType, SystemClock.elapsedRealtime()+timeOrLengthofWait, alarmIntent);
If you are creating PendingIntent of an alarm for past time it will be fired immediately. Example - Schedule alarm for today 8AM but executing code around 11AM will fire immediately.
Solution:
cal.add(Calendar.DATE, 1);
long delay = 24 * 60 * 60 * 1000;
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), delay,pendingIntent);`
This will fire the event on next day at specified time (i.e 8AM);

Categories

Resources