Notification at 0h00 without starting application

7

I would like to notify the user that he has an expense that expires the next day, but without the need for the application to be running, I currently have a code that notifies me from the moment I enter the application, I would like to do so (without user interaction) notify 0h00 every day in case you have any expenses expiring the next day.

Code I already have

LoginActivity - onCreate method

 Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 1);
    calendar.set(Calendar.AM_PM, Calendar.AM);
    Intent myIntent = new Intent(this, MyReceiver.class);
    pendingIntent = PendingIntent.getBroadcast(this, 0, myIntent, 0);
    AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
    alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);

Receiver

public class MyReceiver extends BroadcastReceiver {
    public MyReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent service1 = new Intent(context, MyService.class);
        context.startService(service1);
    }
}

Service

public class MyService extends Service {
    private NotificationManager mManager;

    public MyService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @SuppressWarnings("static-access")
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        Calendar calendar = Calendar.getInstance();
        DespesaDAO DAO = new DespesaDAO(getApplicationContext());
        List<Despesa> list = DAO.getAllVencidasAmanha(calendar);
        if (list.size() > 0) {
            mManager = (NotificationManager) this.getApplicationContext().getSystemService(this.getApplicationContext().NOTIFICATION_SERVICE);
            Intent intent1 = new Intent(this.getApplicationContext(), LoginActivity.class);
            Notification notification = new Notification(R.drawable.ic_launcher, "Existem "+list.size()+" despesas que vencerão amanhã!", System.currentTimeMillis());
            intent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
            PendingIntent pendingNotificationIntent = PendingIntent.getActivity(this.getApplicationContext(), 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
            notification.setLatestEventInfo(this.getApplicationContext(), String.valueOf(list.size()) + " despesas vencem amanhã", "Fique alerta para não se endividar!", pendingNotificationIntent);
            mManager.notify(0, notification);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}
    
asked by anonymous 22.12.2015 / 21:00

1 answer

6

The solution is to define at the start of the device the alarm that will launch the service that generates the notification.

This service should run every day at 0 o'clock.

To do this, in the AndroidManifest.xml , a BroadcastReceiver that responds to action android.intent.action.BOOT_COMPLETED :

<receiver android:name="aSuaPackage.StartUpBootReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>  

Add this permission:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

In BroadcastReceiver set the alarm:

public class StartUpBootReceiver extends BroadcastReceiver {

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

        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {

            // Cria um Calendar para as 0 horas do dia seguinte
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(System.currentTimeMillis());
            calendar.add(Calendar.DAY_OF_MONTH, 1);
            calendar.set(Calendar.HOUR_OF_DAY, 0);

            //PendingIntent para lançar o serviço
            Intent serviceIntent = new Intent(context, MyService.class);
            PendingIntent pendingIntent = PendingIntent.getService(context, 0, serviceIntent, 0);

            //Alarme que se repete todos os dias às 0 horas
            AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);

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

        }
    }
}  

The service should check for any payments to be made and, if so, post the notification.

Notes

  • You must run the application once before it can respond to android.intent.action.BOOT_COMPLETED action . The same applies if your execution has been stopped using Force Close .
  • The application needs to be installed in the phone memory.
  • Using the StartUpBootReceiver is necessary to ensure that the alarm is reset when the device is turned off and then turned on.
  • setInexactRepeating() does not guarantee that the alarm is triggered at exactly the specified time. As this is not relevant in this case, its use is advised to be more resource efficient. If it were to be used setRepeating()
  • The first time that the application runs must set the alarm, otherwise it will only be set when device power is turned off and on.

See this response for a more complete implementation.

    
23.12.2015 / 12:03