I'm trying to make a small application that shows a notification for each 10 minutes until reach 2 hours then the alarm should stop, when I used setRepeat() it works well but I couldn't stop it as I mentioned in my prevoise question HERE,,
I tried with many ways, but it still, there's a problem alarm didn't stop...
I have an idea to use mAlarmManager.set() inside loop, I wrote a code but the loop only start alarm for one time..
so, I'm here to ask how can I implement this idea and showing notification for each 10 minutes until 2 hours !!!
I'll be so appreciated if you help
thanks in advance ...
You don't want to put it in a loop. Rather, have the alarm's pending intent trigger code that checks how much time has gone by and cancels the alarm if appropriate. (This would go in the onReceive method of the class you created the PendingIntent with.)
Alternatively, you can set another alarm for two hours from the start time which will trigger the code to cancel the repeating alarm.
You can set alarm within a for loop too.
Example:
long next=0;
for (int i = 0; i < 12; i++) {
alarmManager.set(AlarmManager.RTC_WAKEUP, mCurrentTime + 10*60*1000 + next, pendingIntent);
next+=10*60*1000;
}
Related
Is there any way to schedule a notification to appear at a specific time?
I am developing an app that reminds a user to change their bandage every 6/12 hours and I wish to send a notification to the user 6/12 hours after they confirm that they have applied the bandage.
Is there any way to do this? I have tried to implement the alarmManager Class however every example I have found uses a specific time of the day as opposed to 6/12 hours after an event.
I have an app which checks whether to show a notification every 24 hours. You can change it to whatever interval you would like.
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
// Create a PendingIntent which AlarmManager would raise.
// You should have a BroadcastReceiver to receive the intent and send a push notification.
setInexactRepeating(
AlarmManager.RTC_WAKEUP,
startAt.toEpochSecond() * 1000,
intervalInMillis,
pendingIntent
)
}
startAt -> Epoch when your alarm should start working (preferably in future). If this is in past, it will immediately boradcast the intent.
intervalInMillis -> Interval in milliseconds. For your case this should be 6 hours.
If your app requires different alarms (notifications) at 6 and 12 hours, I would still go with 6 hours or even 3 hours as the interval. When the broadcast is received, you should check if the app is supposed to send a notification or not. If not, don't do anything.
Read more about Scheduling repeating alarms.
Note: AlarmManager is affected by doze mode and you need to reset all your alarms after the phone restarts. Clubbing this with WorkManager would be ideal. But this should get you started.
Schedule tasks with WorkManager
https://developer.android.com/topic/libraries/architecture/workmanager/
Previously firebase-jobdispatcher-android was working fine now google introduced new WorkManager for scheduling task.
Here is a simple implementaion
http://thetechnocafe.com/how-to-use-workmanager-in-android/
My app needs to update its data every 24hrs. The user should not be able to access some parts of the app if its out of date.
When the app starts up, I check if the database is out of date. But, the users might keep the app open of in the background for a long time, and I need to alert them when the update is required.
What's the best way to do this? My Initial thought was to use some kind of Handler thread and save a timestamp somewhere every time the app was paused, and then calculate the new time and restart the timer on resumer.
This leaves two questions:
How can I detect whenever my app is paused or resumed, regardless of activity?
And what is the best idiom for a long-running timer in Android? (keeping in mid that it has to be able to modify UI components ie show an alert when he time is up)
You could do that, but you should not, instead store the time stamp in the shared preferences whenever the app get closed, when open again read that value again and calculate the difference by getting the actual timestamp.... then after that update if necessary the lapsed time!
timeStamp is just a long value..
and you can get it by just calling the System.currentTimeMillis()
and for the shared preferences use the Class SharedPreferences
You can have a Service do the query every 24 hours for you and notify the user if it fails. You can use the AlarmManager for that. Eg:
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent m_intent = new Intent(this, YourService.class);
PendingIntent pi = PendingIntent.getService(this, 2, m_intent, 0);
alarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000 * 24 * 60 * 60, pi);
The Service can then ask the AlrmManager to call itself after 24 hours again using the above code only.
NOTE: Alarms can be cancelled by the system or the user (force stop). So, this solution comes with its caveats.
In my app I am trying to get the users current location and log it. The user can select an interval. Right now the logging is not happening consistently. Sometimes the logs are just off by a couple seconds and sometimes they are off by a few hours. Also if it is not logging and you turn the GPS off/on then it will start working again. The entire app is based around the idea that you will only be able to get your location using GPS when you use it. I have a few theories as to why this may be.
I am getting the logs by using AlarmManager setExact inside a broadcast receiver. I know that this is not guaranteed to be perfectly accurate and could possible account for a few seconds here and there.
I also know that the GPS can take some time to acquire. Is there a normal range for this time. I could see this taking up to a few minutes possibly but several hours seems like a lot.
I don't know a lot about loopers and am having some difficulty understanding them. I was wondering if the looper in the requestSingleUpdate could have anything to do with it
locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, this, Looper.myLooper());
I know loopers process tasks in the background using a queue and I was't sure if other tasks could get stuck on the queue in front of it causing delays.
My last theory is that it has something to do with not timing out while searching for the GPS signal. If I am searching for a signal every 10 seconds (the fastest allowed) but the phone cannot find a signal the AlarmManager will fire again and I will have two services trying to get a signal. I don't really understand how the services work under the hood so I don't know if this is a possibility or not.
If anyone has any ideas/resources and could point me in the right direction I would really appreciate it.
Here is the code. I can include more if that would be helpful.
#Override
public void onReceive(Context context, Intent intent) {
SharedPreferences pref = context.getSharedPreferences(SettingsActivity.PREFERENCES, Context.MODE_PRIVATE);
if(!pref.getBoolean(SettingsActivity.ARG_TRACK, true)){
return;
}
alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(context.getApplicationContext(), AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
long interval = pref.getLong(SettingsActivity.ARG_TRACKER_INTERVAL, 15000);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmMgr.setExact(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+interval, pendingIntent);
}else{
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
}
context.startService(new Intent(context.getApplicationContext(), AlarmService.class));
}
Inside my service I am calling LocationManager requestSingleUpdate()
locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, this, Looper.myLooper());
In my app I am trying to get the users current location and log it. The user can select an interval. Right now the logging is not happening consistently. Sometimes the logs are just off by a couple seconds and sometimes they are off by a few hours. Also if it is not logging and you turn the GPS off/on then it will start working again. The entire app is based around the idea that you will only be able to get your location using GPS when you use it. I have a few theories as to why this may be.
If i'm not wroing, in your scenario, the interval is not period of location provider. It's directly period of alarm. The story like that
User selects an interval(period), for example 10 minutes.
After 10 minutes(approximately), device wakes up and makes location request to receive single location.
In that case you are facing the gps provider's lag. So, each time when wake up, you are waiting the gps provider to be warm. This is why the logs aren't consistently.
I am getting the logs by using AlarmManager setExact inside a broadcast receiver. I know that this is not guaranteed to be perfectly accurate and could possible account for a few seconds here and there.
You are using exact settings for wake up. This is not actual reason of long lag.
I also know that the GPS can take some time to acquire. Is there a normal range for this time. I could see this taking up to a few minutes possibly but several hours seems like a lot.
You have to wait until GPS provider to be warm. This warming time could change by where you stay at this moment. If you are inside a building, takes long
I don't know a lot about loopers and am having some difficulty understanding them. I was wondering if the looper in the requestSingleUpdate could have anything to do with it
Simply, when you pass a thread's looper here, onLocationChanged() method will be used the looper. But you are already making single request. No more update will be fired. (In your scenario, each wake up is one single location request)
My last theory is that it has something to do with not timing out while searching for the GPS signal. If I am searching for a signal every 10 seconds (the fastest allowed) but the phone cannot find a signal the AlarmManager will fire again and I will have two services trying to get a signal. I don't really understand how the services work under the hood so I don't know if this is a possibility or not.
This is a problem of your scenario. If you set alarm with short period, it's so normal the next wake up could happen. You can follow below things
Due to wait until gps warm, make long alarm period at least 5 minutes
Make timeout scenario, for example wait 1 minute or more until receiving location.
If cant receive location in time, shutdown everything and wait the next wakeup.
I want to create an application that runs for a certain time interval.
[EDITED] By certain time interval, I mean if a user downloads an application from the play store. He can review all the features and functionality for a fixed period of time let say X hours only. After that, we can put any kind restriction (any UI/Navigation restriction so that user cannot review the features).
[The Problem]
what is the easiest as well as an efficient way of doing it? Like I don't think these solutions will work:
Calendar c = Calendar.getInstance();
int seconds = c.get(Calendar.SECOND);
Or
Time now = new Time();
now.setToNow();
What is the best way of putting restrictions (application side or server side as I have seen in some of the game application, where a synchronization is made between a server and application so that user cannot simply change the time and access the features).
So if you want to run your application for a certain period of time in the first run you need to keep a track if its a first run. So you might take set a preference variable so that it can tell you that if its a first run or not.
Now set a CountDownTimer and set it to run for an hour and when the timer is finished, close the Activity by calling finish() to it.
SharedPreferences pref = getSharedPreferences("ApplicationTag", Activity.MODE_PRIVATE);
if (pref.contains("FIRST_LAUNCH")){
finish(); // As you want, it can't be used if the application launches second time.
} else {
// Set the first launch flag to true.
pref.edit.putBoolean("FIRST_LAUNCH", true).commit();
// Start the count down timer
new CountDownTimer(3600000, 1000) {
public void onTick(long millisRemaining) {
// Do nothing
}
public void onFinish() {
// Finish the Activity
finish();
}
}.start();
So you might thinking that what if I switch between Activities. So in that case, you make create a BaseActivity class which will be extended by other Activities in your application. Place the CountDownTimer code there and take a reference of the Context you're in then call context.finish() when the timer is finished.
So in case of you don't want to limit the user for first launch, you need to save the time somehow in your application. When the Activity is finished, you'll get the callback in onDestroy function. So override the onDestroy function and set some preference again with the remaining time in mili seconds. So that you can initialize the timer again when the application starts.
Hope that helps!
Try setting an Alarm for firing any activity after any amount of time you want. Like following:
calendar = Calendar.getInstance();
Intent intent = new Intent(this, ActivityYouWantToStart.class);
PendingIntent pIntent = PendingIntent.getBroadcast(this, 101, intent, 0);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
calendar.add(Calendar.Hour,1);
alarm.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
Call this code when user launches your code for first time and inside ActivityYouWantToStart.class do whatever you want to do after such amount of time.
I have this code called in a Service:
timer.scheduleAtFixedRate(new TimerTask(){
public void run() {
showNotification();
}
}, firstNotify, 86400000L);
It is my understanding that this should cause showNotification() to be called once per day at the same time each day, at the time specified in firstNotify (86400000 being the milliseconds in a day).
However, the notifies were happening approximately every 3 hours on my phone, and a little over 4 hours on my friend's phone. Is there any reason why these would be occurring faster than the specified 1-day period for repeating?
I know its not a direct answer to your question, but you should use AlarmManager in such cases as yours. See setRepeating function.
If your Service is not setup correctly and it is being shut down at some point, the Timer would be recreated and called again after a firstNotify delay. Does this sound possible? You might be better off using AlarmManager to create the timed event.