Good morning, I need help because I have been thinking about this issue for a while and I can not find a solution for my case. Haber if you can help me out.
My application is a work calendar in which users can put reminder notes on the date they want. I have created a notification system which queries the database to see if there is a note on that day and issues the notification if there is one. I have to say that it works well in the short term but in the long term the system closes the application and the service leaving the notifications dead.
I need the system not to close the service that is active because it contains data that when closed is lost.
I leave the code for you to give me ideas on how to optimize the code and how I can solve the problem. I have to say again that the code works but in the short term.
-CODE WHERE THE SERVICE IS STARTED IN THE MAIN ACTIVITY.
private void ActivarServicioNotificaciones(){
EquipoMeses = EquipoLayout;
EquipoJuntoMeses = EquipoJuntoLayout;
mesMeses = MesLayout;
ServicioActivadoMeses = 1;
Intent intent = new Intent(Meses.this, Notificaciones.class);
if (ServicioActivadoLayout == 0){
ToastPersonalizado miToast = new ToastPersonalizado(this, Toast.LENGTH_SHORT);
miToast.show("Activado el servicio de notificaciones del "+ EquipoMeses);
}
intent.putExtra("mes",mesMeses);
intent.putExtra("mesLetra", MesLetra);
intent.putExtra("dia", DiaLayout);
intent.putExtra("dianulo", dianuloMeses);
intent.putExtra("diaSemana", diaSemanaMeses);
intent.putExtra("Equipo", EquipoMeses);
intent.putExtra("EquipoJunto", EquipoJuntoMeses);
intent.putExtra("ServicioActivado", ServicioActivadoMeses);
intent.putExtra("PrimeraNotificacion", PrimeraNotificacionLayout);
intent.putExtra("AlarmaConectadaOnOff", AlarmaConectadaOnOffLayout);
intent.putExtra("notificacionlanzada", notificacionlanzada);
PendingIntent sender = PendingIntent.getService(Meses.this, 0, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 1000 * 59, sender);
startService(intent);
}
-CLASS WHERE THE SERVICE IS MANAGED.
public class Notificaciones extends Service {
public static final String TAG = "Servicio";
private boolean isRunning = false;
private int DiaSer;
private int MesSer;
private int MesSer1;
private String MesSerLetra;
private int hora;
private int minuto;
private String mesnotificacionletra;
private String equiponotificacion;
private String Activ = null;
public String mesLetraServicio;
public int mesServicio;
public int diaServicio;
public int dianuloServicio;
public int diaSemanaServicio;
public String EquipoServicio;
public String EquipoJuntoServicio;
public int ServicioActivadoServicio;
public int NotificacionLanzadaServicio;
private String mesletraServicio;
private Integer mesnotificacion;
private int ContaNotificaciones;
private int PrimeraNotificacionServicio;
private int AlarmaConectadaServicio;
public Notas[] datosLista;
public SQLiteDatabase db;
public ControlNotas usdbh;
public int HayDatos = 0;
private int HoraNotificacion;
private int MinutoNotificacion;
public static final String KEY_TEST = null;
private int ContadorNotificacion = 0;
@Override
public void onCreate() {
isRunning = true;
}
@Override
public int onStartCommand(Intent intent, int flags, final int startId) {
final Calendar c = Calendar.getInstance();
DiaSer = c.get(Calendar.DAY_OF_MONTH);
MesSer = c.get(Calendar.MONTH);
MesSer1 = MesSer + 1;
hora = c.get(Calendar.HOUR_OF_DAY);
minuto = c.get(Calendar.MINUTE);
mesnotificacion = MesSer1;
ComprobarMesPequeño();
mesServicio = intent.getIntExtra("mes", 0);
mesLetraServicio = intent.getStringExtra("mesLetra");
diaServicio = intent.getIntExtra("dia", 0);
dianuloServicio = intent.getIntExtra("dianulo", 0);
diaSemanaServicio = intent.getIntExtra("diaSemana", 0);
EquipoServicio = intent.getStringExtra("Equipo");
EquipoJuntoServicio = intent.getStringExtra("EquipoJunto");
ServicioActivadoServicio = intent.getIntExtra("ServicioActivado", 0);
PrimeraNotificacionServicio = intent.getIntExtra("PrimeraNotificacion", 0);
AlarmaConectadaServicio = intent.getIntExtra("AlarmaConectadaOnOff", 0);
NotificacionLanzadaServicio = intent.getIntExtra("notificacionlanzada", 0);
new Thread(new Runnable() {
@Override
public void run() {
//Abrimos la base de datos 'DBControlNotificacion' en modo escritura
ControlNotificacion cont = new ControlNotificacion(getApplicationContext(), "DBControlNotificacion.sqlite", null, 1);
SQLiteDatabase db = cont.getReadableDatabase();
String cod = "1";
Cursor c = db.rawQuery("SELECT equipo, horanotificacion, minutonotificacion FROM ControlNotificacion where codigo=" + cod, null);
if (c.moveToFirst()) {
String equ = c.getString(0);
int hora = c.getInt(1);
int minuto = c.getInt(2);
equiponotificacion = equ;
HoraNotificacion = hora;
MinutoNotificacion = minuto;
db.close();
c.close();
}
int MinutoMasUno = MinutoNotificacion + 1;
if (hora == HoraNotificacion && minuto == MinutoMasUno){
NotificacionLanzadaServicio = 0;
ContadorNotificacion = 0;
}
if (hora == HoraNotificacion && minuto == MinutoNotificacion && NotificacionLanzadaServicio == 0) {
if (ContadorNotificacion == 0){
//Abrimos la base de datos 'DBUsuarios' en modo escritura
usdbh = new ControlNotas(Notificaciones.this, "DBnotas" + equiponotificacion + ".sqlite", null, 1);
db = usdbh.getReadableDatabase();
Cursor ConsultaNotas = db.rawQuery("SELECT * FROM 'notas' " +
"WHERE diames='" + DiaSer + "'" +
"AND mesmes='" + mesnotificacionletra + "'", null);
if (ConsultaNotas.moveToFirst()) {
//Recorremos el cursor hasta que no haya más registros
datosLista = new Notas[ConsultaNotas.getCount()];
int i = 0;
do {
datosLista[i] = new Notas();
datosLista[i].setDiames(ConsultaNotas.getInt(0));
datosLista[i].setMesmes(ConsultaNotas.getString(1));
datosLista[i].setNota(ConsultaNotas.getString(2));
i++;
} while (ConsultaNotas.moveToNext());
db.close();
if (isRunning) {
// Preparamos el intent que será lanzado si la notificación es seleccionada
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificacionLanzadaServicio =1;
Intent intent = new Intent(Notificaciones.this, Meses.class);
intent.putExtra("mes", mesnotificacion);
intent.putExtra("mesLetra", mesnotificacionletra);
intent.putExtra("dia", DiaSer);
intent.putExtra("dianulo", dianuloServicio);
intent.putExtra("diaSemana", diaSemanaServicio);
intent.putExtra("Equipo", EquipoServicio);
intent.putExtra("EquipoJunto", EquipoJuntoServicio);
intent.putExtra("ServicioActivado", ServicioActivadoServicio);
intent.putExtra("PrimeraNotificacion", PrimeraNotificacionServicio);
intent.putExtra("AlarmaConectadaOnOff", AlarmaConectadaServicio);
intent.putExtra("notificacionlanzada", NotificacionLanzadaServicio);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |Intent.FLAG_ACTIVITY_CLEAR_TOP |Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pIntent = PendingIntent.getActivity(Notificaciones.this, 0, intent, 0);
// Creamos la notificación.
CharSequence ticker = "Aviso de Nota";
CharSequence contentTitle = "Calendario Verallia Sevilla";
CharSequence contentText = "Tienes una nueva nota para hoy";
Notification noti = new NotificationCompat.Builder(Notificaciones.this)
.setContentIntent(pIntent)
.setTicker(ticker)
.setContentTitle(contentTitle)
.setContentText(contentText)
.setSmallIcon(R.drawable.icono_aplicacion_2018_notificacion)
.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000})
.setSound(soundUri)
.build();
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Ocultamos la notificación si ha sido ya seleccionada
noti.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, noti);
ContadorNotificacion = 1;
}
}
}
}
}
}).start();
return Service.START_STICKY;
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onDestroy() {
isRunning = false;
stopSelf();
}
private void ComprobarMesPequeño(){
switch (mesnotificacion){
case 1:
mesnotificacionletra = "Enero";
break;
case 2:
mesnotificacionletra = "Febrero";
break;
case 3:
mesnotificacionletra = "Marzo";
break;
case 4:
mesnotificacionletra = "Abril";
break;
case 5:
mesnotificacionletra = "Mayo";
break;
case 6:
mesnotificacionletra = "Junio";
break;
case 7:
mesnotificacionletra = "Julio";
break;
case 8:
mesnotificacionletra = "Agosto";
break;
case 9:
mesnotificacionletra = "Septiembre";
break;
case 10:
mesnotificacionletra = "Octubre";
break;
case 11:
mesnotificacionletra = "Noviembre";
break;
case 12:
mesnotificacionletra = "Diciembre";
break;
}
}
}
THIS IS WHAT I LEAVE IN THE LOGCAT.
01-11 22:57:39.668 5862-5862/com.navasfj.calendario18 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.navasfj.calendario18, PID: 5862
java.lang.RuntimeException: Unable to start service com.navasfj.calendario18.Notificaciones@af490ce with null: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.content.Intent.getIntExtra(java.lang.String, int)' on a null object reference
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3383)
at android.app.ActivityThread.-wrap21(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1612)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.content.Intent.getIntExtra(java.lang.String, int)' on a null object reference
at com.navasfj.calendario18.Notificaciones.onStartCommand(Notificaciones.java:91)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3366)
at android.app.ActivityThread.-wrap21(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1612)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)
Please, if it is not clear what I want to do, tell me and I will try to clarify it better.
Thanks in advance for your help.