How to repeat a minute-to-minute notification

Asked

Viewed 876 times

2

I’m creating a app simple that gets a notification every time I click a button on my layout, everything works perfectly. Now I want this notification to be repeated for example every minute until I deactivate it. Can someone give me a hint as to how I can do this?? :).

Here is my code.

public class MainActivity extends Activity {
    @Override
    public void onCreate (Bundle savedInstanceState) {
        super.onCreate (savedInstanceState);
        setContentView (R.layout.main);
        Button createNotification = (Button) findViewById
                (R.id.create_notification_button);
        createNotification.setOnClickListener (new View.OnClickListener() {
            @Override
            public void onClick (View v) {
                Intent intent = new Intent (MainActivity.this ,
                        notificationActivity.class);
                PendingIntent pendingIntent = PendingIntent.getActivity
                        (MainActivity.this, 0, intent, 0);
                Notification notification = new Notification.Builder (MainActivity.this)
                        .setContentTitle(getString(R.string.new_notification))
                        .setContentText(getString (R.string.notification_content))
                        .setSmallIcon (R.drawable.ic_launcher)
                        .setContentIntent(pendingIntent)
                        .getNotification();
                notification.flags = Notification.FLAG_AUTO_CANCEL;
                NotificationManager notificationManager =
                        (NotificationManager) getSystemService (NOTIFICATION_SERVICE);
                notificationManager.notify (0, notification);
            }
        });
    }
}

3 answers

5


Create a service that uses Handlerthread to launch notifications periodically.

public class NotifyService extends Service {

    private HandlerThread handlerThread;
    private Handler handler;

    //Define o tempo entre notificações, altere como quiser
    private final int TEMPO_ENTRE_NOTIFICAÇOES_SEGUNDOS = 10;

    @Override
    public void onCreate() {
        Log.d("NotifyService","onCreate");

        handlerThread = new HandlerThread("HandlerThread");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Log.d("NotifyService","onStart");

        //Previne que seja executado em subsequentes chamadas a onStartCommand
        if(!handlerThread.isAlive()) {
            Log.d("NotifyService","Notificações iniciadas");
            handlerThread.start();
            handler = new Handler(handlerThread.getLooper());

            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    sendNotification();
                    handler.postDelayed(this, 1000 * TEMPO_ENTRE_NOTIFICAÇOES_SEGUNDOS);
                }
            };
            handler.post(runnable);
        }
        return Service.START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("NotifyService","Notificações terminadas");
        handlerThread.quit();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private void sendNotification(){
        Intent intent = new Intent (this ,
                notificationActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity
                (this, 0, intent, 0);
        Notification notification = new Notification.Builder (this)
                .setContentTitle(getString(R.string.new_notification))
                .setContentText(getString (R.string.notification_content))

                .setSmallIcon(R.drawable.ic_launcher)
                .setContentIntent(pendingIntent)
                .getNotification();
        notification.flags = Notification.FLAG_AUTO_CANCEL;
        NotificationManager notificationManager =
                (NotificationManager) getSystemService (NOTIFICATION_SERVICE);
        notificationManager.notify (0, notification);
        Log.d("NotifyService", "notificação enviada");
    }
}

Declare the service on Androidmanifest.xml

<application>
    ...
    ...
    <service
        android:name=".NotifyService"
        android:exported="false" />
</application>

To start creating notifications use:

startService(new Intent(this, NotifyService.class));

Notifications will be launched with the time interval indicated in TEMPO_ENTRE_NOTIFICAÇOES_SEGUNDOS, even if it leaves the application.

To stop notifications use:

stopService(new Intent(this, NotifyService.class))

Example with two buttons, one to start and one to stop:

public class MainActivity extends Activity {

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

        Button startNotification = (Button)findViewById(R.id.start_notification_button);
        Button stopNotification = (Button)findViewById(R.id.stop_notification_button);

        startNotification.setOnClickListener (new View.OnClickListener() {
            @Override
            public void onClick (View v) {
                startService(new Intent(MainActivity.this, NotifyService.class));
            }
        });

        stopNotification.setOnClickListener (new View.OnClickListener() {
            @Override
            public void onClick (View v) {
                stopService(new Intent(MainActivity.this, NotifyService.class));
            }
        });
    }
}
  • Thanks... I’ll give you to analyze the code any doubt I warn...

  • I have made all the modifications recommended by you by logging in when clicking does not enter any notification. No Logcat stops the following message "Skipped 47 frames! The application may be Doing Too Much work on its main thread.".

  • The code was tested before posting it. I don’t understand this message in this context, since the service code (launch notification) does not run on main thread. Test the service with the example Activity I posted.

  • I used the example Activity and the lines . setContentTitle(getString(R.string.new_notification)) . setContentText(getString (R.string.notification_content)) appear with error in new_notification and notification_content. What should I do there??

  • This is the code that creates the notification, it was copied from your question. It is supposed that these string Resources have been created by you. For testing you can replace getString(R.string.xxxx) for "qualquer coisa"

  • I removed the error but still no notification sent... If you can send the project you have tested to my email please... [email protected]

  • You declared the service on Androidmanifest.xml?

  • Yes I did declare..

  • Note that it has to be declared within the tag <application>.

  • @Amaral you’re the guy, it turns out I had opened another Aplication tag and had not noticed. Now it’s working perfectly. Thank you so much for your help and patience.

  • 1

    Switching to +1. = D

Show 6 more comments

3

There are several ways to do this, but you can use the ScheduledExecutorService in a Service. See how it would look:

public class MyService extends Service {

    // definição do loop de 60 em 60 segundos, equivalente a 1 min
    private static final int SECONDS = 60 ;

    // indica inicilização
    int mStartMode;

    //interface para clientes
     IBinder mBinder;

    //indica se o onRebind está sendo usado
    boolean mAllowRebind;

    private ScheduledExecutorService sTaskExecutor;

    @Override
    public void onCreate() {
        Toast.makeText(this, "Serviço iniciado!!", Toast.LENGTH_SHORT).show();
        sTaskExecutor = Executors.newScheduledThreadPool(1);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        if (!sTaskExecutor.isShutdown()) {
            sTaskExecutor.scheduleAtFixedRate(new Runnable() {
                public void run() {

                    /* aqui você insere a notificação  */
                    android.util.Log.wtf(MyService.class.getSimpleName(), " Em loop!!!");
                }
            }, 0, SECONDS, TimeUnit.SECONDS);
        }

        return mStartMode;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return mAllowRebind;
    }

    @Override
    public void onDestroy() {
        sTaskExecutor.shutdown();
        Toast.makeText(this, "Serviço finalizado!!", Toast.LENGTH_SHORT).show();
    }
}

In the Manifest:

<application>
    ...
     <service android:name=".MyService" android:exported="false"/>
</application>

To INITIATE the Service user the method startService in your class MainActivity. Behold:

startService(new Intent(getBaseContext(), MyService.class));

To STOP the Service user the method stopService. Behold:

stopService(new Intent(getBaseContext(), MyService.class));

For more details, you can see in the documentation.

  • this class continues running even after the app is minimized or closed?

  • I’ll take a look at the documentation Ack Lay ... Thanks

  • Mr_anderson only works when I click the button.

  • Yes I want to receive notifications when the app is working in the background too..

  • How to disable notifications?

  • Stop service, but notifications will continue to be launched.

  • I saw that you edited the reply but, although the notifications are no longer being released, the runnable will continue to be executed. The service, despite the method onDestroy() can not be "cleaned" by the GC, because the runnable has a reference to it.

  • There was the question of ensuring that if the method onStartCommand() be called again, a new Task Force should not be created. I think that if (!sTaskExecutor.isShutdown()) solves this problem. I just think that using a Scheduledexecutorservice is a bit exaggerated for the terefa in question. However I will give +1.

Show 3 more comments

0

You can also use the AlarmManager to manage the sending of notifications.

First create a class that extends BroadcastReceiver

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class DispararNotificacao extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        // faz o que vc precisa aqui para disparar sua notificação
    }
} 

Then just add the order to AlarmManager within your onClick

Calendar calendar = Calendar.getInstance();

Intent tarefaIntent = new Intent(getApplicationContext(), DispararNotificacao.class);

PendingIntent tarefaPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 
    requestCode, tarefaIntent, PendingIntent.FLAG_CANCEL_CURRENT);

final long inteval = minuto * 60 * 1000;

AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);

alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 
    inteval, tarefaPendingIntent);

To disable notifications just cancel on AlamrManager

Intent tarefaIntent = new Intent(getApplicationContext(), DispararNotificacao.class);
PendingIntent tarefaPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 
    requestCode, tarefaIntent, PendingIntent.FLAG_CANCEL_CURRENT);
alarmManager.cancel(tarefaPendingIntent);
  • Using an Alarmmanager to launch events from minute to minute is not recommended. View note in the documentation.

  • Christian Beregula would give me an example??

  • then what could look good in this situation??

  • @Yaniksantos I will put an answer.

  • I’ll be waiting then...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.