I have a GPS service whose work is to fetch the coordinate into a server. This service suppose to be run 24/7. but it is somehow killed in between.
This is happing only in android v 2.3. On android v2.2 it's running fine.
In this service , i am using "LocationManager" and it's method "requestLocationUpdates" which is creating a loop.This loop is responsible for fetching the coordinates. So my goal is to keep the loop running.
So what to do, to make by service run 24/7.
This server suppose to be run 24/7
You cannot do that. This is not possible in any real sense of the term, as you have discovered. It is also not a good design choice at all.
If you absolutely need it to be running all the time, you need to
acquire a PARTIAL_WAKE_LOCK via PowerManager. This will keep the CPU
on all the time, and your program running. Be prepared for a shocking
decline in battery life.
Instead use AlarmManager. You can schedule a PendingIntent via the AlarmManager thats starts the service at the relevant point in time to do it's work. When done, kill the service again.
Below is a sample code showing how the AlarmManager is used which will launch the intent to start YourService in 5 minutes from now:
// get a calendar with the current time
Calendar cal = Calendar.getInstance();
// add 5 minutes to the calendar object
cal.add(Calendar.MINUTE, 5);
Intent intent = new Intent(ctx, YourService.class);
PendingIntent pi = PendingIntent.getService(this, 123, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pi);
Please use repeating Alarm Manager which start your service after a given time period
private void setAlarm() {
AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(), LocationUpdateService.class);
intent.putExtra("locationSendingAlarm", true);
PendingIntent pendingIntent = PendingIntent.getService(this, AppConstants.PENDING_INTENET_LOCATION_SENDING_ALARM_ID, intent,0);
try {
alarmManager.cancel(pendingIntent);
} catch (Exception e) {
}
int timeForAlarm=5*1000*60; // 5 minutes
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+timeForAlarm, timeForAlarm,pendingIntent);
}
Related
I am trying to poll a device for long/lat every minute or so... I have been researching and found a few things. I was thinking of using:
PeriodicWorkRequestBuilder() - however, I have read that it can only execute every 15 minutes at a minimum...
What tech/design pattern are available to me, if I wanted to poll for data in a shorter period?
Are foreground services my only choice?
You can Use any Runnable but when app closed it will not working .
Foreground service is best choice but in android 9+, it will confuse the user
this is the link that show to you how use it:
Timer
BUT
I advice you to use an AlarmManager that work like work manager but it response better, you can Use Countdown timer for it, link below will help You to use it:
AlarmManager
Edited:
sample for open activity with alarm manager
Intent intent = new Intent(this, YOUR_MAIN_ACTIVITY.class);
intent.setAction(Intent.ACTION_MAIN);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
PendingIntent pendingIntent = PendingIntent.getActivity(this, ID,
intent, 0);
final long DELAY_IN_MILLIS = DELAY_IN_MILLI_SECONDS+
System.currentTimeMillis();
AlarmManager alarmManager = (AlarmManager)
getSystemService(Activity.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, DELAY_IN_MILLIS,pendingIntent);
and there is a full example for you:
Example
My requirement is set Notification for specific time like user birthday or holiday
I am using AlarmManager for scheduling notification using broadcast receiver
Code is working fine in 6.0 (even when app is killed,swiped from recent list) but not working on Android 8.1.0 (Mf : Oppo)
Readed This and This and many answers but not find any helpfull
any idea how to solve this issue
Here is my code
AlarmManager am = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
//creating a new intent specifying the broadcast receiver\
Intent i = new Intent(this, HolidayBroadcast.class);
i.putExtra("eventName",islamicHoliday.getEventName());
i.putExtra("dateH", testTmp.getCalendar().getTimeInMillis());
i.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
//creating a pending intent using the intent
PendingIntent pi = PendingIntent.getBroadcast(this, new Random().nextInt(), i, PendingIntent.FLAG_UPDATE_CURRENT);
//setting alarm
if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.M) {
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,getTimeInMillis(), pi);
}
else
{
am.setExact(AlarmManager.RTC_WAKEUP, getTimeInMillis(), pi);
}
You can use workmanager as mentioned in link.It supports all api version and easy to use because it uses backward compatibility to API level 14
https://developer.android.com/topic/libraries/architecture/workmanager
https://medium.com/androiddevelopers/introducing-workmanager-2083bcfc4712
If your task is time critical, WorkManager API is not recommended as for your alarm manager not working properly, on Android 8 use
AlarmManager.setexactandallowwhileidle(), to set exact time and allow wakeup notification while app is killed.
I'm having a problem with the Android AlarmManager. I want to show a notification everyday at 00:01 AM. When i test the notification during the day at something like 11:30 AM the notification does show up. But when i test it at 00:01 AM nothing shows up.
I think this has something to do with my phone being asleep after a few hours of no activity at 00:01 AM, but I am not sure. Does anybody have a solution for this? Thanks in advance.
MainActivity:
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager manager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 1);
Calendar now = Calendar.getInstance();
now.setTimeInMillis(System.currentTimeMillis());
if (calendar.before(now)) {
calendar.add(Calendar.DAY_OF_MONTH, 1);
manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
} else {
manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
}
AlarmReceiver:
private static int NOTIFICATION_ID;
private NotificationManager notificationManager;
private PendingIntent pendingIntent;
Intent mIntent;
#Override
public void onReceive(Context context, Intent intent) {
NOTIFICATION_ID = random.nextInt(9999 - 1000) + 1000;
notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
mIntent = new Intent(context, BirthdayActivity.class);
pendingIntent = PendingIntent.getActivity(context, NOTIFICATION_ID, mIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setContentTitle("Name");
builder.setContentIntent(pendingIntent);
notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, builder.build());
}
Manifest:
<receiver android:name=".utils.AlarmReceiver" android:enabled="true">
</receiver>
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
I think everything is right with your code. You can check whether the alarm is set or not using this command on your android studio terminal.
adb shell dumpsys alarms >dump.txt
and then search for your package name in that file. This will confirm whether your alarm is set successfully or not.
Next you are using setRepeating which means system can adjust the delivery time. To deliver the alarm at the exact time use setExact
here is a excerpt from the official android documentation:
Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above.
From the api docs:
Note: as of API 19, all repeating alarms are inexact. If your
application needs precise delivery times then it must use one-time
exact alarms, rescheduling each time as described above. Legacy
applications whose targetSdkVersion is earlier than API 19 will
continue to have all of their alarms, including repeating alarms,
treated as exact.
https://developer.android.com/reference/android/app/AlarmManager.html#setRepeating(int, long, long, android.app.PendingIntent)
There are a few questions you should answer.
Does this really need to be exact?
If the user is sleeping can this wait until they wake up their phone?
Exact alarms are often discouraged as they disregard the state of the phone. For example, its not "nice" to the user to sync your app when they aren't even looking at their phone.
If you are connecting to a server and updating some data, I'd recommend a 'push' approach rather than a 'pull' approach.
They system only holds a wakelock while delivering the alarm notification to the AlarmReceiver. Unless there is some other reason for the device to stay awake, it is entirely possible that it will go back to sleep, before the Intent is delivered to the Activity.
Have a look at WakefulBroadcastReceiver
This question already has answers here:
Start Android Service after every 5 minutes
(3 answers)
Closed 7 years ago.
I know this question is asked before, but I didn't get any answer, I want to create an intent service that run a thread all the time, but when I get out from the app my service is stopped then the thread stopped too. I need to create something to wake up the service every some minutes. or something to prevent killing the service even when app is killed or closed.
this is how I start my service
Intent intent= new Intent(Intent.ACTION_SYNC,null,this,IntentServ.class);
startService(intent);
For this you can use the AlarmManager that could start your service for every 1 Hour. For Example :
AlarmManager mgr = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent notificationIntent = new Intent(context,
UpdateService.class);
PendingIntent pendingIntent=PendingIntent.getService(context, requestCode, Intent.parseIntent(), 0);
mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), AlarmManager.INTERVAL_HOUR, pendingIntent);
AlarmManager and PendingIntentare what you need in this case.
Follow below example :
AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
/* --- Create pending intent, which will be executed when wake-up --- */
PendingIntent operation = getUpdatePolicyOperation();
am.set(AlarmManager.RTC, alarmTime, operation); // alarm time is millisecond time in milliseconds that the alarm should go off, using the appropriate clock (depending on the alarm type).
You can read more about alarm mode in AlarmManager in Here or take a tutorial in Here
Hope it's helped.
Use normal Service with android.app.AlarmManager.
Don't need to use WakefulBroadcastReceiver.
I want to program an app that has two independent, repetitive alarms. There are two classes seem to be able do this: AlarmManager and AlarmClock. I've tested AlarmManager, but when Android restarts all alarms are cleared.
Which should I use?
Use BroadcastReceiver to handle Android OS boot broadcast and reschedule your alarms.
AlarmManager services allow you to schedule your application to be run at some point in the future. When an alarm goes off, the Intent that had been registered for it is broadcast by the system, automatically starting the target application if it is not already running.
You may find the SO post helpful Android AlarmManager
AlarmManager mgr=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i=new Intent(context, OnAlarmReceiver.class);
PendingIntent pi=PendingIntent.getBroadcast(context, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), PERIOD, pi);
Whereas AlarmClock provider contains an Intent action and extras that can be used to start an Activity to set a new alarm in an alarm clock application.