0

In my project I want to change a flag value in SharedPreference in particular time every day ,I have implemented the AlarmManager but It is not performing the task . My function to call my receiver class :

public void changeAttendaceFlag(){
        Log.d(TAG,"changeAttendaceFlag !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY,14);
        calendar.set(Calendar.MINUTE,23);
        calendar.set(Calendar.SECOND,10);
        Intent activateLogin = new Intent(getApplicationContext(),Attendance.class);
        PendingIntent pendingIntent =
                PendingIntent.getBroadcast(getApplicationContext(),101,activateLogin,PendingIntent.FLAG_UPDATE_CURRENT);

        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY,pendingIntent);
    }

My receiver class :

public class Attendance extends BroadcastReceiver {
    FcmSession fcmSession;
    private static final String TAG = "Attendance";
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, " Attendance Called !!!!!!!!!!!!!!!!!!!!", Toast.LENGTH_SHORT).show();
        fcmSession = new FcmSession(context);
        fcmSession.store_dialog_value(true);
        UtilsMethods utilsMethods = new UtilsMethods();
        String time = utilsMethods.getCurrentDateAndTime();
        Log.d(TAG,"change attendance flag  :"+time);
    }
}
Sidhartha
  • 988
  • 4
  • 19
  • 39
  • where did you put this code? in a service? – Rashid Jul 10 '17 at 09:10
  • @SecretCoder In my launcher activity (LoginActivity) – Sidhartha Jul 10 '17 at 09:21
  • did you close the app and wait for the time? – Rashid Jul 10 '17 at 09:22
  • @SecretCoder Yes . – Sidhartha Jul 10 '17 at 09:24
  • ow, thats the reason why it wont perform the task. when your task is in your Activity and when you close it, the instance of that activity will be destroyed. In order to retain the instance you should implement it inside your background service. the background service wont lose its instance even if you close the app. Refer here on how to start creating a service https://developer.android.com/training/run-background-service/create-service.html – Rashid Jul 10 '17 at 09:28
  • alaram manager set() and setRepeat functions are not accurate , it may give u lag of 1 to 3 minutes , you should wait for at least 1 to 3 minutes. If you want ur alarm to ring at exact time then you should setExact() method and handle repeat logic Attendance class. You can set another alarm is attendance class for next day. But setExact added in api level 19. refer to link https://developer.android.com/reference/android/app/AlarmManager.html#setExact(int, long, android.app.PendingIntent) – Hassan Munir Jul 10 '17 at 09:33
  • @SecretCoder Can you please share some other link . – Sidhartha Jul 10 '17 at 09:56
  • here https://www.survivingwithandroid.com/2014/01/android-service-tutorial-2.html. just copy paste what you see here and transfer your Pending Intent code here. Run the function on `onStartCommand`. Remember to put correct onStart command (eg. START_STICKY, START_NOT_STICKY) – Rashid Jul 10 '17 at 09:59
  • @SecretCoder from onStartCommand(Intent intent, int flags, int startId) I am calling my function ,but how to use "onStart command (eg. START_STICKY, START_NOT_STICKY" ,actually I don't understand this part. – Sidhartha Jul 10 '17 at 11:33
  • Have you put the `BroadcastReceiver` in your manifest? Is it ever getting called? – David Wasser Jul 12 '17 at 13:45

2 Answers2

1

Try to use Inexact instead of just simple Repeating for targetSdk greater than 19 API. Check Note at this LINK.

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.

So, Change and try with below line:-

alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY,pendingIntent);

Updated:

Also, In some phone devices(like Xiaomi, Lenovo) app needs to put in AutoStart list. For reference answer check this link.

Nitin Patel
  • 1,605
  • 13
  • 31
1

This is just part of the answer. Here is how you implement the service onStartCommand

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // this is where you run your changeAttendaceFlag() method
    return START_STICKY; // this will make your service recreate when your app is closed
}

The following return type will be available once your class extends Service

START_STICKY : Using this return value will make your service recreate when you close your app. When you force close your app the service will recreated but the intent wont be redeliver therefore the service will always run without doing anything.

START_NOT_STICKY : Using this return value will make your service not recreate when closed.

START_REDELIVER_INTENT : Using this return value will make your service function similar to START_STICKY but this time when theres an intent, it will redeliver it.

Note: Data will be reinstantiate once app is closed since the service will be recreated. Save your data in SharedPreferences or SQLite DB.

For autostart, you can do that in settings but when you restart your phone, it will disable autostart and you need to enable it which is a really bad user experience(I think this is for some phone). You can do autostart on your service as well by implementing a BroadcastReceiver for BOOT_COMPLETED. Here is a great example https://stackoverflow.com/a/4562747/5870896

Community
  • 1
  • 1
Rashid
  • 1,700
  • 1
  • 23
  • 56