1

My application targets KITKAT and up android version and i am trying to create repetitive notification daily via Alarm Manager below is my code :

public class AlarmReceiver extends BroadcastReceiver {
    public static final String MY_ACTION = "mymasterpeice.foreverservice.myaction";

    @Override
    public void onReceive(Context context, Intent intent) {

        if (intent.getAction().equals(MY_ACTION)) {
            // Do something here
            // For our recurring task, we'll just display a message
            Toast.makeText(context, "I'm running", Toast.LENGTH_SHORT).show();
            // displayNotification(context, "Checkout New Articles");
            sendNotification(context, "Checkout New Articles - Team");

        }


    }

    /**
     * Issues a notification to inform the user that server has sent a message.
     */
    private static void sendNotification(Context context, String message) {
        if (message != null && !TextUtils.isEmpty(message)) {
            int icon = R.mipmap.ic_launcher;
            long when = System.currentTimeMillis();
            NotificationManager notificationManager = (NotificationManager)
                    context.getSystemService(Context.NOTIFICATION_SERVICE);
            String title = context.getString(R.string.app_name);
            Intent notificationIntent = new Intent(context, MainActivity.class);
            // set intent so it does not start a new activity
            notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
                    Intent.FLAG_ACTIVITY_SINGLE_TOP);
            PendingIntent intent =
                    PendingIntent.getActivity(context, 0, notificationIntent, 0);
            Notification.Builder builder = new Notification.Builder(context);
            notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
                    Intent.FLAG_ACTIVITY_SINGLE_TOP);
            builder.setSmallIcon(icon)
                    .setContentTitle(title)
                    .setContentText(message)
                    .setContentIntent(intent);
            Notification notification = builder.getNotification();
            notificationManager.notify(icon, notification);
        }
    }


}

Main Activity :

public class MainActivity extends AppCompatActivity {

    private String TAG=MainActivity.class.getSimpleName();
    public static final String MY_ACTION = "mymasterpeice.foreverservice.myaction";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setRecusrringTimer();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    private void setRecusrringTimer() {
        Intent myIntent = new Intent(MY_ACTION);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(
                this, 0, myIntent, 0);
        AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
        Calendar firingCal = Calendar.getInstance();
        Calendar currentCal = Calendar.getInstance();
        firingCal.set(Calendar.HOUR, 7); // At the hour you wanna fire
        firingCal.set(Calendar.MINUTE, 0); // Particular minute
        firingCal.set(Calendar.SECOND, 0); // particular second
        long intendedTime = firingCal.getTimeInMillis();
        long currentTime = currentCal.getTimeInMillis();
        if (intendedTime >= currentTime) // you can add buffer time too here to ignore some small differences in milliseconds
        {
            alarmManager.setRepeating(AlarmManager.RTC,
                    intendedTime, AlarmManager.INTERVAL_DAY,
                    pendingIntent);
            Log.d(TAG, "setRecusrringTimer ");
        } else {
            intendedTime = firingCal.getTimeInMillis();
            Log.d(TAG, "setRecusrringTimer ");
            alarmManager.setRepeating(AlarmManager.RTC,
                    intendedTime, AlarmManager.INTERVAL_DAY,
                    pendingIntent);

        }
    }

}

Manifest :

    <receiver android:name=".AlarmReceiver">
        <intent-filter>
            <action android:name="mymasterpeice.foreverservice.myaction"/>
        </intent-filter>
    </receiver>

Issue is This code runs properly on Kitkat device until app is in memory , there are some delays like as in doc specified :

Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.

But When app is not in memory the alarm manager does not show notification . I am specifically targeting Kitkat and above version of android.

KOTIOS
  • 11,177
  • 3
  • 39
  • 66
  • It sounds like the device you're testing on is actually forcibly stopping the app when you remove it from the recent apps list, which, from what I've read, is just how that's implemented by some vendors. If that's the case, then your alarms are being cleared, and the app is being put back into the _stopped_ state. Try swiping your app from recents, then check if the "Force stop" button is greyed out in your app's info page in Settings. Also, check if your alarms still show in a `dumpsys alarm`, as described in [this post](http://stackoverflow.com/a/6523295/2850651). – Mike M. Jan 28 '16 at 09:06
  • @MikeM. I tried to just clear from recent app and didnt wanted to actually go in setting and force close the app but still it didnt worked. Any Clue why so and even if app is forced closed will the alarm manager removes all the alarm ? i need that justification. – KOTIOS Jan 28 '16 at 09:27
  • "I tried to just clear from recent app and didnt wanted to actually go in setting and force close the app but still it didnt worked." - I'm sorry, but I don't understand what you're saying here. "...even if app is forced closed will the alarm manager removes all the alarm ?" - If your app is forcibly closed, its alarms are cleared. Also, being in the _stopped_ state, your statically registered Receiver won't work anyway, until the user starts your app again. – Mike M. Jan 28 '16 at 09:34
  • so basically is there any way where some android component would create notification in background? good example i saw was some of famous games like candy crush would just create notification at some point of time in future to reminder user of something evenwhen app is forced closed and in stopped state in some point of time it creates notification. – KOTIOS Jan 28 '16 at 09:38
  • I don't know how Candy Crush accomplishes that, if that is indeed possible. – Mike M. Jan 28 '16 at 09:45
  • @MyMasterPeice did fix this issue. Any solution ? – bCliks Apr 08 '16 at 09:56

1 Answers1

0

I lost 1 month of my time for the same issue. Finally I found the solution. For the recent Android versions(exact version I am not sure ), an option called 'Auto Launch' have been introduced, which means the user can actually configure whether any app can be automatically started or not. So please check whether your app has permission for auto launch. This setting location may vay based on phone manufacturer. So you need to search for this 'Auto Lanuch' option in your phone settings. Even if it doesn't work, try removing your app from the 'Optimizations List' as well, which you can find in the settings.