0

I would like my app to show a notification daily at a specific time. To do this I have put the following code in the onCreate method of my MainActivity class (which is opened by default when the app is started).

Mainactivity.class

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setNotification(Mainactivity.this);
    }

    public void setNotification(Context context) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY,12);
        calendar.set(Calendar.MINUTE,1);
        calendar.set(Calendar.SECOND,0);
        long c = System.currentTimeMillis();
        long t = calendar.getTimeInMillis();
        if (t <= c) {
            calendar.add(Calendar.DATE, 1);
        }
        Intent intent = new Intent(this, NotificationReciever.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 100, intent, 
        PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);    alarmManager.set(AlarmManager,RTC_WAKEUP,calendar.getTimeInMillis(),pendingIntent);

        boolean alarmUp = (PendingIntent.getBroadcast(MainActivity.this, 100,
        new Intent(this, NotificationReciever.class),
        PendingIntent.FLAG_NO_CREATE) != null);
        if (alarmUp) {
          Toast.makeText(MainActivity.this,"Aan",Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(MainActivity.this,"Niet aan",Toast.LENGTH_SHORT).show();
        }
    }

Then in the class NotificationReceiver I simply construct and initiate the notification. It does this at the correct time, but also always when the app is started. I do not know how to stop the notification from stopping to initiate whenever the app is started, can someone help me with this?

One thing that I have tried is to check if the current time is larger than or equal to the time where the notification should be initiated. I did that by implementing the following code in the NotificationReceiver class:

NotificationReceiver.class

public class NotificationReciever extends BroadcastReceiver{

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

        NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);

        Intent new_intent = new Intent(context, MainActivity.class);
        new_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

        PendingIntent pendingIntent = PendingIntent.getActivity(context, 100, new_intent, PendingIntent.FLAG_UPDATE_CURRENT);

        NotificationCompat.Builder notification = new NotificationCompat.Builder(context)
            .setContentIntent(pendingIntent)
            .setSmallIcon(R.drawable.ic_stat_name)
            .setTicker("ticker_title")
            .setContentTitle("content_title")
            .setContentText("description")
            .setAutoCancel(true);

        notificationManager.notify(0, notification.build());

        MainActivity mainActivity = new MainActivity();
        mainActivity.setNotification(context);
    }
}

However, this way the notification does not get initiated when the app is started before, in this case, 12:01, but it still does after this time.. (btw, the following code is added into my manifest)

<receiver android:name=".NotificationReciever"/>
BramH
  • 221
  • 5
  • 24
  • You're close. Checking the alarm time against the current time is exactly what you want to do, but instead of immediately showing the `Notification` if the current time is greater, you just want to add a day to the alarm `Calendar` - e.g., `calendar.add(Calendar.DATE, 1);` - and set the alarm as usual. – Mike M. Oct 20 '17 at 00:27
  • I will try that soon, but beforehand a question about it.. Is it then correct that if the 1 in "calendar.add(Calendar.DATE, 1);" would be replaced by a 2, the alarm would trigger every other day? – BramH Oct 20 '17 at 08:06
  • I edited the question, by inserting "calendar.add(Calendar.DATE, 1);" but the notification is still triggered every time the app is started.. – BramH Oct 20 '17 at 12:18
  • You inserted `calendar.set(Calendar.DATE, 1);`, not `add()`, and it's in the wrong place. You want to add a day in the `if` block. – Mike M. Oct 20 '17 at 12:21
  • I deleted my previous comment, its actually still not working.. The notification keeps showing after the set time every time the app is started – BramH Oct 20 '17 at 13:05
  • You'll have to edit your question with the full, exact code as you have it now. – Mike M. Oct 20 '17 at 13:10
  • I did that now, its not the actual full code since that would be way to long. These are the only parts that have to do with the notifications. – BramH Oct 21 '17 at 10:17
  • Yeah, that's what I meant. You need to do the time check and adjustment before you set the alarm, not in `onReceive()`, after the alarm has already fired. Also, if you need the alarms to fire at the exact time you set, `setRepeating()` is not what you want, since it's inexact since KitKat. Use an exact, one-time method, and set the alarm again for the next day when it fires. – Mike M. Oct 21 '17 at 10:26
  • I edited my code again to what I think you meant. And it works, as in, the notification is only shown at the specified time. The only thing is that I have to wait one day to see if it also works tomorrow haha. Do you think it will or do you see a mistake already? – BramH Oct 21 '17 at 11:17
  • Yeah, a couple. You've got the time check backwards. It should be `if (t <= c)`. And the only thing that should be in the `if` block is `calendar.add(Calendar.DATE, 1);`. All of the alarm code should come after it, 'cause you still need to set the alarm either way. You can use adb to see if your alarm is getting set, so you don't have to wait: https://stackoverflow.com/q/28742884. After you get that all working, you'll need to move that alarm set code into a method that you can call from the Receiver too, so you can set tomorrow's alarm when one fires. But get that other stuff working first. – Mike M. Oct 21 '17 at 11:33
  • I edited my code again but I really dont know what to do next, how to use adb – BramH Oct 21 '17 at 12:22
  • The time check is still backwards. Everything looks OK. As for adb, about all I can do is point you to [the developer docs](https://developer.android.com/studio/command-line/adb.html). You might be able to find some easier-to-follow tutorials, if you look around, but it's not really something we can teach in comments here. You could do a coupla other things to test directly, though. After you set the alarm, change the date/time on your device to something closer to the alarm time. Or fiddle with your code slightly to just set the alarm a few minutes ahead, instead of adding a full day. – Mike M. Oct 21 '17 at 12:33
  • A yes, forgot to edit the time check here, i did it in my code though. I understand that teaching it here would be undoable, I will certainly study it later when I have more time. Also I will try using the tips you just gave me. Thanks a lot for your help, I really appreciate it! :) – BramH Oct 21 '17 at 12:41
  • I have tried a lot of things and this is the best I came up with, I think. But the problem I'm running into is the error: “System services not available to Activities before onCreate()”. I have also tried to put the code that is in my setNotification() method, in the NotificationReviever class, but then the ALARM_SERVICE is not supported. Do you maybe know how to solve this? – BramH Oct 24 '17 at 13:53

2 Answers2

0

You should use a service job to schedule task

Francky Vincent
  • 453
  • 4
  • 12
0

Use Firebase Job Dispatcher , you can also use JobScheduler but Firebase Job Dispatcher will be easy. Rest your Choice.

coder3101
  • 3,920
  • 3
  • 24
  • 28
  • I am quite new to Android Studio and I cannot find any helpful tutorial regarding Firebase Job Dispatcher.. Do you have an idea how I should implement it? – BramH Oct 19 '17 at 17:09
  • Firebase Job Dispatcher's README.md is more than enough , follow this and you will understand : https://github.com/firebase/firebase-jobdispatcher-android/blob/master/README.md – coder3101 Oct 20 '17 at 08:35
  • Thank you for your answer, I think this method is more general and easier to use. At the moment I do not have the time to look into this but i will keep it in mind for later :) – BramH Oct 20 '17 at 12:20