Hello, I was having the same problem and after a long time searching for the answer and testing I got using AlarmManager and BroadcastReceiver, what I needed:
I have a web system where someone registers notifications in the database, and an API that returns a json with the requests, I needed something to run with the app open or closed checking if it has new messages and notifying the user.
Home
My AndroidManifest.xml
<receiver
android:name=".Servico.BootReciever"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="ALARME_DISPARADO2"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
On my onCreate of Activity
boolean alarmeativo = (PendingIntent.getBroadcast( this, 0, new Intent( "ALARME_DISPARADO2" ), PendingIntent.FLAG_NO_CREATE ) == null);
if(alarmeativo) {
Intent intent = new Intent( "ALARME_DISPARADO2" );
PendingIntent p = PendingIntent.getBroadcast( this, 0, intent, 0 );
Calendar c = Calendar.getInstance();
c.setTimeInMillis( System.currentTimeMillis() );
c.add( Calendar.SECOND, 3 );
AlarmManager alarm = (AlarmManager) getSystemService( ALARM_SERVICE );
alarm.set( AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), p );
}
I check if the alarm is already created, I assign the Intent that will be executed referring to my BroadcastReceiver, assign a time to start and configure the alarm RTC_WAKEUP to execute even with the device blogged, done in BroadcastReceiver, start a Task, because I need to post a post on a web page, using recursion to continue to post.
Home
My BootReciever.java
public class BootReciever extends BroadcastReceiver {
public static Usuario us;
public static Notifi not;
public static NotifiSetor notSet;
public static Agenda notAg;
public static boolean Iniciar = true;
public static boolean saida;
int x = 0;
@Override
public void onReceive(Context context, Intent intent) {
Iniciar = false;
Usuario u = new Usuario( context );
u.Select();
us = u;
Notifi n = new Notifi( context );
not = n;
NotifiSetor ns = new NotifiSetor(context );
notSet = ns;
Agenda ag = new Agenda( context );
notAg = ag;
NotificationTask us = new NotificationTask();
us.execute(context);
}
public boolean isOnline(Context context) {
boolean conectado;
try {
ConnectivityManager conectivtyManager = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE );
if (conectivtyManager.getActiveNetworkInfo() != null
&& conectivtyManager.getActiveNetworkInfo().isAvailable()
&& conectivtyManager.getActiveNetworkInfo().isConnected()) {
conectado = true;
} else {
conectado = false;
}
} catch (Exception e) {
conectado = false;
}
return conectado;
}
private class NotificationTask extends AsyncTask<Context, Void, Context> {
@Override
protected Context doInBackground(Context... ct) {
saida = false;
try {
Agenda a = new Agenda(notAg.getCt());
List<Agenda> list = a.SelectExibir();
if(list != null) {
for (int x = 0; x < list.size(); x++) {
long date1 = System.currentTimeMillis();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
String dateString = sdf.format(date1);
if(list.get(x).getExibir().equals(dateString)) {
Calendar cal = Calendar.getInstance( TimeZone.getTimeZone("GMT"));
Date currentLocalTime = cal.getTime();
DateFormat date = new SimpleDateFormat("dd-MM-yyyy");
date.setTimeZone(TimeZone.getTimeZone("GMT"));
String localTime = date.format(currentLocalTime);
NewMessageNotification.notify(ct[0], list.get(x).getTitulo(), list.get(x).getMensagem(), list.get(x).getID());
a.setID(list.get(x).getID());
a.setUltimo_Exib(localTime);
a.UpdateExibir();
}
}
}
} catch (Exception e) {
}
if(isOnline(ct[0])) {
//Log.d("",String.valueOf( x++ ));
// notificaçoes agendadas
try {
//buscar na api
// buscar no webservice
String json = "json a ser enviando para API";
HttpService servi = new HttpService();
String retorno = servi.post(json);
try {
JSONObject jsonObj = new JSONObject(retorno);
JSONArray array = jsonObj.getJSONArray("Res");
if (jsonObj.getBoolean("Response")) {
for (int i = 0; i < array.length(); i++) {
// notificacao
notAg.setID(array.getJSONObject(i).getInt("ID"));
if (!notAg.ValidaId()) {
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
//cal.add(Calendar.DAY_OF_MONTH, -1);
Date currentLocalTime = cal.getTime();
DateFormat date = new SimpleDateFormat("dd-MM-yyyy");
date.setTimeZone(TimeZone.getTimeZone("GMT"));
String localTime = date.format(currentLocalTime);
notAg.setTitulo(array.getJSONObject(i).getString("TITULO"));
notAg.setMensagem(array.getJSONObject(i).getString("MENSAGEM"));
notAg.setCadastro(array.getJSONObject(i).getString("DATA_CAD"));
notAg.setExibir(array.getJSONObject(i).getString("REPETIR"));
notAg.setUltimo_Exib(localTime);
notAg.setStatus(array.getJSONObject(i).getInt("STATUS"));
notAg.Insert();
} else {
notAg.setTitulo(array.getJSONObject(i).getString("TITULO"));
notAg.setMensagem(array.getJSONObject(i).getString("MENSAGEM"));
notAg.setCadastro(array.getJSONObject(i).getString("DATA_CAD"));
notAg.setExibir(array.getJSONObject(i).getString("REPETIR"));
notAg.setStatus(array.getJSONObject(i).getInt("STATUS"));
notAg.Update();
}
}
}
} catch (Exception e) {
}
} catch (Exception e) {
// Restore interrupt status.
//Thread.currentThread().interrupt();
}
// notificaçoes geral equipe
try {
//buscar na api
// buscar no webservice
String json = "json a ser enviando para API";
HttpService servi = new HttpService();
String retorno = servi.post(json);
try {
JSONObject jsonObj = new JSONObject(retorno);
JSONArray array = jsonObj.getJSONArray("Res");
if (jsonObj.getBoolean("Response")) {
for (int i = 0; i < array.length(); i++) {
// notificacao
not.setID(array.getJSONObject(i).getInt("ID"));
if (!not.ValidaId()) {
not.setTitulo(array.getJSONObject(i).getString("TITULO"));
not.setMensagem(array.getJSONObject(i).getString("MENSAGEM"));
not.setData(array.getJSONObject(i).getString("DATA_CAD"));
not.setStatus(array.getJSONObject(i).getInt("STATUS"));
not.Insert();
NewMessageNotification.notify(ct[0], not.getTitulo(), not.getMensagem(), not.getID());
}
}
}
} catch (Exception e) {
}
} catch (Exception e) {
// Restore interrupt status.
//Thread.currentThread().interrupt();
}
// notificaçoes geral setor
try {
//buscar na api
// buscar no webservice
String json = "json a ser enviando para API";
HttpService servi = new HttpService();
String retorno = servi.post(json);
try {
JSONObject jsonObj = new JSONObject(retorno);
JSONArray array = jsonObj.getJSONArray("Res");
if (jsonObj.getBoolean("Response")) {
for (int i = 0; i < array.length(); i++) {
// notificacao
notSet.setID(array.getJSONObject(i).getInt("ID"));
if (!notSet.ValidaId()) {
notSet.setTitulo(array.getJSONObject(i).getString("TITULO"));
notSet.setMensagem(array.getJSONObject(i).getString("MENSAGEM"));
notSet.setData(array.getJSONObject(i).getString("DATA_CAD"));
notSet.setStatus(array.getJSONObject(i).getInt("STATUS"));
notSet.Insert();
NewMessageNotification.notify(ct[0], notSet.getTitulo(), notSet.getMensagem(), notSet.getID());
}
}
}
} catch (Exception e) {
}
// exibir
} catch (Exception e) {
// Restore interrupt status.
//Thread.currentThread().interrupt();
}
}
try {
// recursividade para continuar executando
doInBackground( ct[0] );
} catch(Exception e) {
}
return ct[0];
}
@Override
protected void onPostExecute(Context result) {
// Após a inserção da nota, vamos mostrar um Toast ao usuário
saida = true;
Iniciar = true;
doInBackground(result);
}
}
}
Result
I / art: Increasing code cache capacity to 128KB
D / 14: 46: 36: - > Started
D / 14: 46: 41: - > Started
D / 14: 46: 42: - > Started
D / 14: 46: 44: - > Started
D / 14: 46: 45: - > Started
D / 14: 46: 46: - > Started
D / 14: 46: 48: - > Started
D / 14: 46: 49: - > Started
D / 14: 46: 50: - > Started
D / 14: 46: 52: - > Started
D / 14: 46: 53: - > Started
D / 14: 46: 54: - > Started
D / 14: 46: 56: - > Started
D / 14: 46: 56: - > Started
D / 14: 46: 57: - > Started
D / 14: 46: 58: - > Started
D / 14: 46: 59: - > Started
D / 14: 47: 00: - > Started
D / 14: 47: 01: - > Started
D / 14: 47: 03: - > Started
D / 14: 47: 04: - > Started
D / 14: 47: 07: - > Started
D / 14: 47: 09: - > Started
D / 14: 47: 11: - > Started
D / 14: 47: 12: - > Started
D / 14: 47: 15: - > Started
D / 14: 47: 16: - > Started
D / 14: 47: 17: - > Started
D / 14: 47: 18: - > Started
D / 14: 47: 19: - > Started
D / 14: 47: 20: - > Started
D / 14: 47: 21: - > Started
D / 14: 47: 22: - > Started
D / 14: 47: 23: - > Started
D / 14: 47: 24: - > Started
D / 14: 47: 25: - > Started
D / 14: 47: 26: - > Started
D / 14: 47: 27: - > Started
D / 14: 47: 28: - > Started
D / 14: 47: 30: > Started
D / 14: 47: 32: - > Started
D / 14: 47: 33: - > Started
D / 14: 47: 34: - > Started
D / 14: 47: 35: - > Started
D / 14: 47: 36: - > Started
D / 14: 47: 37: - > Started
D / 14: 47: 38: - > Started
D / 14: 47: 38: - > Started
D / 14: 47: 39: - > Started
D / 14: 47: 40: - > Started
D / 14: 47: 41: - > Started
D / 14: 47: 42: - > Started
D / 14: 47: 43: - > Started
D / 14: 47: 43: - > Started
D / 14: 47: 44: - > Started
D / 14: 47: 45: - > Started
D / 14: 47: 46: - > Started
D / 14: 47: 46: - > Started
D / 14: 47: 47: - > Started
D / 14: 47: 48: - > Started
D / 14: 47: 49: - > Started
D / 14: 47: 50: - > Started
I / art: Background sticky concurrent mark sweep GC freed 3085 (212KB) AllocSpace objects, 2 (40KB) LOS objects, 1% free, 28MB / 28MB, paused 5.805ms total 16.525ms
D / 14: 47: 50: - > Started
D / 14: 47: 51: - > Started
D / 14: 47: 52: - > Started
D / 14: 47: 53: - > Started
D / 14: 47: 54: - > Started
D / 14: 47: 55: - > Started
D / 14: 47: 56: - > Started
D / 14: 47: 57: - > Started
D / 14: 47: 58: - > Started
D / 14: 47: 58: - > Started
D / 14: 47: 59: - > Started
D / 14: 48: 00: - > Started
D / 14: 48: 01: - > Started
D / 14: 48: 02: - > Started
D / 14: 48: 02: - > Started
D / 14: 48: 03: - > Started
D / 14: 48: 04: - > Started
D / 14: 48: 05: - > Started
D / 14: 48: 06: - > Started
D / 14: 48: 07: - > Started
D / 14: 48: 09: - > Started
D / 14: 48: 10: - > Started
D / 14: 48: 11: - > Started
D / 14: 48: 12: - > Started
D / 14: 48: 13: - > Started
D / 14: 48: 13: - > Started
D / 14: 48: 14: - > Started
D / 14: 48: 15: - > Started
D / 14: 48: 16: - > Started
D / 14: 48: 17: - > Started
D / 14: 48: 18: - > Started
D / 14: 48: 19: - > Started
D / 14: 48: 20: - > Started
D / 14: 48: 21: - > Started
D / 14: 48: 22: - > Started
D / 14: 48: 22: - > Started
Application terminated.
And testing on my phone worked properly and with little delay time to display the notifications with the application closed and open, you can also call a Service or an IntetService in onReceive.