Best way to call a function at specific timestamp [duplicate] - java

This question already has answers here:
Using Alarmmanager to start a service at specific time
(6 answers)
Closed 6 years ago.
I want to call a function when System timestamp reaches to specific time.
is there anyway better than a CountDownTimer ?
It should be called on a service because i want it still run when app closes.
thanks a lot.

You have to use BroadcastReceiver along with AlarmManager Like this.
//Create alarm manager
AlarmManager malarmMngr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
//Create pending intent & register it to your alarm notifier class
Intent intent = new Intent(this, yourBroadcastReceiver.class);
PendingIntent mPendInt = PendingIntent.getBroadcast(this, 0, intent, 0);
//set your time stamp (for once in future)
malarmMngr .set(AlarmManager.RTC_WAKEUP, yourtimestamp, mPendInt);
Now create yourBroadcastReceiver class to call function.
public class yourBroadcastReceiver extends BroadcastReceiver {
public MyReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
// This method is called when this BroadcastReceiver receives an Intent broadcast.
// Call your function here
}
}

Related

Java Android create canvas that will pop-up automatically at a specified date

I am developing a simple android app that manages events(An event contains a name, a description, and a date). For example: Somebody's birthday or something like that.
I want a canvas to pop up by itself at the specified date(even if I'm not in the application). I managed to create a Toast using AlarmManager and BroadcastReceiver which pop ups automatically at the specified date. But I can only write text to a Toast.
Is there any way to create a canvas that will pop up similar to a Toast?
My alarm manager:
AlarmManager alarms = (AlarmManager)this.getSystemService(Context.ALARM_SERVICE);
IntentFilter filter = new IntentFilter("ALARM_ACTION");
registerReceiver(receiver, filter);
Intent intent = new Intent("ALARM_ACTION");
intent.putExtra("param", "It's your mom's birthday!");
PendingIntent operation = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarms.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+1000,operation) ;
And my Receiver class:
public class Receiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//I want to replace the Toast with a canvas.
Toast.makeText(context, intent.getStringExtra("param"), Toast.LENGTH_SHORT).show();
}
}

Android set() and setExact() alarms firing at incorrect intervals

I'm developing an app that should perform a certain task every 60 seconds. Since there's some accuracy problems with alarms in Android 4.4+, where all alarms are inexact, I've opted for the chained model: A BroadcastReceiver fires the first alarm, and each alarm in turn sets the next alarm.
The problem is that, even though I'm setting the alarms at intervals of 60 seconds (60000 ms), the alarms trigger at 5 second intervals, and sometimes even less. I've tested the code on my Nexus 5 (Android 5.1.1) and on an Android 5.0.1 emulator, both giving the same result.
I should point out that both receivers are registered on the AndroidManifest and my application has the RECEIVE_BOOT_COMPLETED permission.
EDIT: setExact() causes exactly the same problem
StartupReceiver.java (BroadcastReceiver for BOOT_COMPLETED):
public class StartupReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Got the BOOT_COMPLETED signal");
// Get the first alarm to be invoked immediately
AlarmReceiver.setNextScanAlarm(context, 0);
}
}
AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Start the service
Intent startServiceIntent = new Intent(context, BackgroundService.class);
startServiceIntent.putExtra("interval", 60000);
startServiceIntent.putExtra("action", "scan");
context.startService(startServiceIntent);
// Schedule the next alarm
setNextScanAlarm(context, 60000);
}
public static void setNextScanAlarm(Context context, int interval) {
Intent scanIntent = new Intent(context, AlarmReceiver.class);
scanIntent.putExtra("interval", interval);
scanIntent.putExtra("action", "scan");
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
0,
scanIntent,
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
interval,
pendingIntent);
}
}
What could be the problem?
I believe because this is an alarm clock when calling
alarmManager.set(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
interval,
pendingIntent);
The variable you are calling interval is the amount of time you want to elapse UNTIL the next alarm , but when you think about this when does it know to start? More so, when does time actually equal zero? When you create it? No. When you call .set()? No. It is actually zero upon BOOT. So you are asking it to launch 60 seconds after boot, and your asking for this everytime, this time will have already elapsed.
This is where the confusion is, and where you should probably just use a call like new
Handler.postDelayed(Runnnable r, 60000) instead of an alarm Manager. It will be much more accurate and will not be subject to some problems with understanding the Android Operating System and its alarms/clocks/etc/etc.
But for your specific case I believe you could solve it by accessing System function calls/variables. So inside of your function setNextScanAlarm() I believe it would look like this:
public static void setNextScanAlarm(Context context, int interval) {
//create the intent the same way as before
Intent scanIntent = new Intent(context, AlarmReceiver.class);
scanIntent.putExtra("interval", interval);
scanIntent.putExtra("action", "scan");
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
0,
scanIntent,
PendingIntent.FLAG_ONE_SHOT);
//create new variables to calculate the correct time for this to go off
long timeRightNow = System.elapsedRealTime() //use something else if you change AlarmManager type
long timeWhenIShouldGoOff = timeRightNow + interval;
//use the new timeWhenIShouldGoOff variable instead of interval
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
timeWhenIShouldGoOff,
pendingIntent);
}
See my answer to a similar question.
I use postDelayed() instead of AlarmManager for the short time intervals (less than 1 minute), and AlarmManager for long.

Android AlarmManager firing at random times

I'm developing an application which has to show some Notifications and that has to download some data two times a day, so i created a Service for launching my Notifications and a BroadcastReceiver which should (depending on the time) run my NotificationService and later also my DownloadService.
My problem is now, that the AlarmManager-alarm i created should call fire every hour (not important if 1 or 2 minutes less or more), and it does that for about 3 to 4 hours but then it runs randomly and also multiple times in between for example 7 and 8 o'clock.
I have no idea where the problem could be so here is my code:
Activity:
Intent myIntent = new Intent(OverviewActivity.this, Receiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(OverviewActivity.this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, notifCal.getTimeInMillis(), AlarmManager.INTERVAL_HOUR, pendingIntent);
Receiver:
public class Receiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
Intent notificationService = new Intent(context, NotificationService.class);
context.startService(notificationService);<br/>
}
}
Thanks in advance,
momob114
Each time your Activity is fired your app is cancelling and recreating the Alarm which could be the cause of the seemingly random calls (which could actually correspond to the time you opened the app, or one hour later).
Note in case you still want to do that, instead of cancelling the previous alarm you can just call :
PendingIntent pendingIntent = PendingIntent.getBroadcast(OverviewActivity.this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Keep also in mind that a reboot of the device will clear any alarms that you might have set. So you'll probably want to create a BroadcastReceiver listening for the android.intent.action.BOOT_COMPLETED action in order to set your repeating alarm then.

android stopwatch/timer app - switching back to app when time runs out

I'm developing an app, as mentioned in title. I need somehow to manage that application will be running/counting time even when user starts/switches to another application. Well, as I learned from another discussion at stackoverflow.com, there is no need to create service that works in background and pointlessly burden processor with counting time when app is not active.
Everything what is needed to be done is to store current time when user switch to another app, compare it to time when he switches back and update the UI according to difference between these times. That's for stopwatch mode. When in timer mode, I need to automatically switch back to application according to time, that is app's UI showing when going o background. What could be the best solution suitable for this and can you give me please some simple examples for this?
Use AlarmManager for that. AlarmManager allows you to schedule tasks and get notified when they are fired.
So use AlarmManager
public class MainActivity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//call function where you want
timeout();
}
public void timeout()
{ //time in milliseconds 1 minute
Long time = new GregorianCalendar().getTimeInMillis()+60*1000; //i.e.60*1000=1minute
// create an Intent and set the class which will execute when Alarm triggers, here we have
Intent intentAlarm = new Intent(this, AlarmReciever.class);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,time, PendingIntent.getBroadcast(this,1, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT));
}
}
Here is broadcast class:
public class AlarmReciever extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
// show dialog or what you want
}
}
Don't forgot to edit AndroidMainfest:
//permission
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
//our receiver
<receiver android:name=".AlarmReciever"/>

Call Server function and popup on Broadcast receiver android

I have an application in which I have to call off an alarm/notification each 30 Minutes.
I want the feature like
1- If app is closed, it open the app, Call a dialog box. On click it will call a serverFunction and if MainActivity is running, update its UI.
2- If the app is already opened , Call a dialog box. On click it will call a serverFunction. Since MainActivity is may or may NOT on the top, update its UI Or NOT.
In My MainActivity.class
private void callNotification()
{
AlarmManager service = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(this, AlarmReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(this, 0, i,PendingIntent.FLAG_CANCEL_CURRENT);
Calendar time = Calendar.getInstance();
time.setTimeInMillis(System.currentTimeMillis());
time.add(Calendar.SECOND, Constants.TIME_CONSTANT);
service.set(AlarmManager.RTC_WAKEUP ,time.getTimeInMillis(), pending);
}
public class AlarmReceiver extends BroadcastReceiver
{
#Override
public void onReceive(final Context context, Intent intent)
{
}
}
The problem here is , I can't put a dialog box in onReceive since context is not Activity context. What If the app is opened , Now how am I suppose to implement above features.
In your onReceive place this to call your activity:
Intent i = new Intent(context, AlertActivity.class);
i.setFlags
startActivity(i);
Once you are in your activity you can open up a dialog.
I recommend you use a different activity than your main one to handle displaying the alert, as it makes sense from a design standpoint and it also makes implementation easier. Remember you can make Activities look like dialogs...

Categories

Resources