start a service with Alarmmanager at specific date and time and Repeating
it's better to use job scheduler or firebase dispatcher for your requirement
refer this links
https://medium.com/google-developers/scheduling-jobs-like-a-pro-with-jobscheduler-286ef8510129
https://github.com/firebase/firebase-jobdispatcher-android
Using Alarmmanager to start a service at specific time
HI friends,
After a lot of researching and with reference from "Pentium10"'s question on the same topic i managed to get it working. Though i still cant understand why the "date" concept and the Calendar(non GregorianCalendar) object which i have mentioned in the question are not working correctly.
Calendar cur_cal = new GregorianCalendar();
cur_cal.setTimeInMillis(System.currentTimeMillis());//set the current time and date for this calendar
Calendar cal = new GregorianCalendar();
cal.add(Calendar.DAY_OF_YEAR, cur_cal.get(Calendar.DAY_OF_YEAR));
cal.set(Calendar.HOUR_OF_DAY, 18);
cal.set(Calendar.MINUTE, 32);
cal.set(Calendar.SECOND, cur_cal.get(Calendar.SECOND));
cal.set(Calendar.MILLISECOND, cur_cal.get(Calendar.MILLISECOND));
cal.set(Calendar.DATE, cur_cal.get(Calendar.DATE));
cal.set(Calendar.MONTH, cur_cal.get(Calendar.MONTH));
Intent intent = new Intent(ProfileList.this, IntentBroadcastedReceiver.class);
PendingIntent pintent = PendingIntent.getService(ProfileList.this, 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 30*1000, pintent);
Using Alarm Manager at specific time
Here's a sample code of using the AlarmManager
, you will need to change date and time according to your needs. I put it for today at 23:59
// Pending intent to be fired when alarm occurrs. In this case, open the AlarmActivity
Intent intent = new Intent(getApplicationContext(), AlarmActivity.class);
PendingIntent alarmIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
// Set the alarm for today at 23:59
calendar = Calendar.getInstance(TimeZone.getTimeZone("IST"));
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),
alarmIntent);
In the given date-time the Intent will be fired so you need to make you logic in the AlarmActivity. You could also change the intent to start a Service or fire a Broadcast message
alarm manager can't start at exact time in android
after lots of researches, I finally found API 26 added a new method for pending intent called getForeGroundService()
so the code should look like this :
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener( view -> startBackup());
}
private void startBackup() {
Intent serviceIntent = new Intent(getApplicationContext(), ExampleService.class);
Calendar cal = initCalendar(10, 0, 0);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= 26) {
PendingIntent pintent = PendingIntent.getForegroundService(getApplicationContext(), 6546548, serviceIntent, 0);
alarm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pintent);
}else if (Build.VERSION.SDK_INT >= 23) {
PendingIntent pintent = PendingIntent.getService(getApplicationContext(), 6546548, serviceIntent, 0);
alarm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pintent);
} else if (Build.VERSION.SDK_INT >= 19) {
PendingIntent pintent = PendingIntent.getService(getApplicationContext(), 6546548, serviceIntent, 0);
alarm.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis() , pintent);
} else {
PendingIntent pintent = PendingIntent.getService(getApplicationContext(), 6546548, serviceIntent, 0);
alarm.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis() , pintent);
}
}
private Calendar initCalendar(int hour, int minute, int second) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, second);
return calendar;
}
}
Run code every day at a specific time - AlarmManager
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.
Inexact scheduling means the time between any two successive firings of the alarm may vary. Thats what happening in your case i guess.To overcome the exact time issue i think you should use one shot alarm.But in this case you need to reschedule it for next day. and so on.
You can get a very clear understanding from the Documentation setrepeating , setInexactRepeating.
EDIT:- TO optimizing DOZE mode
In Case you are Using setAndAllowWhileIdle()
or setExactAndAllowWhileIdle()
,
Then you must read This Document which says :-
Neither setAndAllowWhileIdle() nor setExactAndAllowWhileIdle() can fire alarms more than once per 9 minutes, per app.
Use alarmManager and service to perform schedule notification only during specific time period
I was thinking to rework this code so that the alarmManager is fired at waketime and stopped at sleepTime, all while inside the service is a Timer that fires the notification method at specific intervals? Is there a better way to go about doing this?
To my mind, forget thinking of a 'better' way, it seems the only way. Using a timer to control (enable/disable) another timer isn't so strange and makes complete sense to me.
How to trigger a background service in android on specific time?
Hi Please use this code it will help to fill your desires.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 12);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
PendingIntent pi = PendingIntent.getService(this, 0,
new Intent(this, Service_Apps.class),PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pi);
Related Topics
How to Get the Android Emulator's Ip Address
How to Send a Post Request Using Volley with String Body
How to Store(Bitmap Image) and Retrieve Image from SQLite Database in Android
Handling Registration Id Changes in Google Cloud Messaging on Android
Understanding Colors on Android (Six Characters)
Android: Combining Text & Image on a Button or Imagebutton
More Than One File Was Found with Os Independent Path 'Meta-Inf/License'
Android: Scale a Drawable or Background Image
Android Studio Marks R in Red with Error Message "Cannot Resolve Symbol R", But Build Succeeds
Using Alarmmanager to Start a Service at Specific Time
How to Run a Method Every X Seconds
How to Configure Gradle to Work "Offline" (Using Cached Dependencies)
Getinstance() Doesn't Work with Other Location Than Us-Central1 in Realtime Database
Android: Create Spinner Programmatically from Array