Source: https://dhimitraq.wordpress.com/2012/11/27/using-intentservice-with-alarmmanager-to-schedule-alarms/
Github: https://github.com/CS-Worcester/TaskButler
You need to create a service to execute your requests in the background and you should not place your notification code within the Oncreate() method. Maybe this is happening.
I advise you to register two Broadcastreceivers, and a service and also get permission to use wakelock, getting Boot_completed signal.
Androidmanifest.xml:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application>
<receiver android:name=".service.OnBootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".service.OnAlarmReceiver" >
</receiver>
<service android:name=".service.TaskButlerService" >
</service>
</application>
This is a Broadcastreceiver for the full ONBOOT, used to reschedule alarms with Alarmmanager. There are only 2 lines of code in the Onreceive() method, which is because its own Onreceive() is necessarily short. The first line acquires a partial wakelock to keep the CPU running while our Intentservice is running.
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
/**
* BroadCastReceiver para android.intent.action.BOOT_COMPLETED
* passa toda a responsabilidade para TaskButlerService.
* @author Dhimitraq Jorgji
*
*/
public class OnBootReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
WakefulIntentService.acquireStaticLock(context); //acquire a partial WakeLock
context.startService(new Intent(context, TaskButlerService.class)); //start TaskButlerService
}
}
Intentservice is my favorite way of doing things in the background. Normally I don’t put Intentservice directly, and I suggest you do the same; define a synchronized method to acquire a wakelock before continuing with what you need to accomplish.
import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
/**
* Acquires a partial WakeLock, allows TaskButtlerService to keep the CPU alive
* until the work is done.
* @author Dhimitraq Jorgji
*
*/
public class WakefulIntentService extends IntentService {
public static final String
LOCK_NAME_STATIC="edu.worcester.cs499summer2012.TaskButlerService.Static";;
public static final String
LOCK_NAME_LOCAL="edu.worcester.cs499summer2012.TaskButlerService.Local";
private static PowerManager.WakeLock lockStatic=null;
private PowerManager.WakeLock lockLocal=null;
public WakefulIntentService(String name) {
super(name);
}
/ **
* Para Adquirir um wakelock estático, é preciso também chamar esta dentro da classe
* Que chama StartService ()
*
* /
public static void acquireStaticLock(Context context) {
getLock(context).acquire();
}
synchronized private static PowerManager.WakeLock getLock(Context context) {
if (lockStatic==null) {
PowerManager
mgr=(PowerManager)context.getSystemService(Context.POWER_SERVICE);
lockStatic=mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
LOCK_NAME_STATIC);
lockStatic.setReferenceCounted(true);
}
return(lockStatic);
}
@Override
public void onCreate() {
super.onCreate();
PowerManager mgr=(PowerManager)getSystemService(Context.POWER_SERVICE);
lockLocal=mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
LOCK_NAME_LOCAL);
lockLocal.setReferenceCounted(true);
}
@Override
public void onStart(Intent intent, final int startId) {
lockLocal.acquire();
super.onStart(intent, startId);
getLock(this).release();
}
@Override
protected void onHandleIntent(Intent intent) {
lockLocal.release();
}
}
Now we can simply inherit Wakefulintentservice , and do all our work with a simple onHandleIntent(Intent) method. The method can be called from anywhere in your program and it will take care of everything in a background like any Service, also safely, since it holds a wakelock until the method ends at the point where it returns the closure.
import java.util.List;
import android.content.Intent;
import edu.worcester.cs499summer2012.database.TasksDataSource;
import edu.worcester.cs499summer2012.task.Task;
/ **
* Uma IntentService cuida da criação de alarmes para Task Butler
* Para lembrar o usuário de eventos
* author Dhimitraq Jorgji
*
* /
public class TaskButlerService extends WakefulIntentService{
public TaskButlerService() {
super("TaskButlerService");
}
@Override
protected void onHandleIntent(Intent intent) {
TasksDataSource db = TasksDataSource.getInstance(this); //get access to the instance of TasksDataSource
TaskAlarm alarm = new TaskAlarm();
List<Task> tasks = db.getAllTasks(); //Get a list of all the tasks there
for (Task task : tasks) {
// Cancelar alarme existente
alarm.cancelAlarm(this, task.getID());
//alarmes de aviso
if(task.isPastDue()){
alarm.setReminder(this, task.getID());
}
//alarmes de repetição
if(task.isRepeating() && task.isCompleted()){
task = alarm.setRepeatingAlarm(this, task.getID());
}
//alarmes regulares
if(!task.isCompleted() && (task.getDateDue() >= System.currentTimeMillis())){
alarm.setAlarm(this, task);
}
}
super.onHandleIntent(intent);
}
}
At this point, you only need a Broadcastreceiver to receive your alarms .
package edu.worcester.cs499summer2012.service;
import edu.worcester.cs499summer2012.database.TasksDataSource;
import edu.worcester.cs499summer2012.task.Task;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
/**
* BroadCastReceiver for Alarms, displays notifications as it receives alarm
* and then starts TaskButlerService to update alarm schedule with AlarmManager
* @author Dhimitraq Jorgji
*
*/
public class OnAlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
WakefulIntentService.acquireStaticLock(context); //adquirindo WakeLock
//enviando notificação com taskID
NotificationHelper notification = new NotificationHelper();
Bundle bundle = intent.getExtras();
int id = bundle.getInt(Task.EXTRA_TASK_ID);
TasksDataSource db = TasksDataSource.getInstance(context);
Task task = db.getTask(id);
if(task.hasFinalDateDue() || task.getPriority() == Task.URGENT){
notification.sendPersistentNotification(context, task); // Básica notificação
} else {
notification.sendBasicNotification(context, task); //Básica notificação
}
context.startService(new Intent(context, TaskButlerService.class)); //iniciando TaskButlerService
}
}
In what method is this code located? I believe it is in
onCreate()
, but I could be wrong.– mutlei
yes, onCreate()`
– Ilgner de Oliveira
So that’s why he makes a notification every time he opens the app. To make notifications only at specific times, I can’t say how.
notificationBuilder
and thenotificationManager
Activity objects, and then run the build of the Notifications in specific methods.– mutlei
that was why I knew , but I do not know how to do by specific time, I saw something of Alarmmanager but I did not understand how to use
– Ilgner de Oliveira