studio - alarms in android
Android AlarmManager se detiene cuando la actividad muere (9)
Inicio AlarmManager con PendingIntent y en algunos teléfonos la alarma no responde. En algunos dispositivos funciona bien, en otros falla. He hecho algunas pruebas en diferentes teléfonos.
Nexus funciona bien, también Samsung Galaxy S4 zoom (4.2) funciona bien.
Samsung note 2 (4.3) funciona bien.
La alarma OPPO (4.4.4) muere.
También he implementado receptores de difusión que funcionan como deberían en todos los dispositivos.
Log.v(TAG, "START ALARM");
Intent intentAlarm = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(), 0, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, 1000, 5000, pendingIntent);
¿Podrías mostrarnos el código AlarmReceiver.class? Quizás necesites usar return START_STICKY;
en su método onStartCommand?
Esto es solo una suposición, pero creo que el problema tiene que ver con la API. A partir de KitKat, el sistema desordena el AlarmManager. Quizás considere usar otra cosa para los sistemas en abd por encima de kitkat.
"Nota: a partir de la entrega de alarmas de API 19 (KITKAT) es inexacto: el sistema operativo cambiará las alarmas para minimizar el despertar y el uso de la batería. Hay nuevas API para aplicaciones que necesitan garantías estrictas de entrega; consulte setWindow (int, long, long , PendingIntent) y setExact (int, long, PendingIntent). Las aplicaciones cuyo targetSdkVersion es anterior a API 19 continuarán viendo el comportamiento anterior en el que todas las alarmas se entregan exactamente cuando se las solicita. "
Tomado de http://developer.android.com/reference/android/app/AlarmManager.html
Intenta lo siguiente:
1) Agregue el permiso Wake_lock a su manifiesto.
<uses-permission android:name="android.permission.WAKE_LOCK">
2) Cambiar
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, 1000, 5000, pendingIntent);
con
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000, 5000, pendingIntent);
Podría haber un par de problemas diferentes en el trabajo aquí:
- El tipo de alarma que está solicitando (
ELAPSED_REALTIME
) no activará el dispositivo para enviar la alarma. En cambio, si caduca mientras el dispositivo está inactivo, se entregará la próxima vez que se active el dispositivo. - El valor de
triggerAtMillis
de1000
está solicitando la primera alarma a 1 segundo después del inicio del dispositivo. Si el dispositivo ya ha estado funcionando y usted solicita esta alarma, es posible que la primera alarma no se active y que las siguientes no se programen. Esto es solo una conjetura, no lo he verificado mirando las fuentes 4.4.4 de AOSP
La gestión de alarmas se cambió en API 19 (Android 4.4) para manejar la recopilación de temporizadores de alarma (todos son inexactos de forma predeterminada) y este cambio podría haber afectado las cosas para la segunda viñeta. Puede intentar cambiar el valor de triggerAtMillis
para que sea (SystemClock.elapsedRealtime() + 1000)
Tenga en cuenta que si necesita que el dispositivo se _WAKEUP
deberá usar una variante de alarma _WAKEUP
y también hacer que su BroadcastReceiver
tome un bloqueo de activación que su Service
o Activity
libera cuando _WAKEUP
manejar la alarma.
Sus alarmas continuarán existiendo después de que su aplicación se cierre normalmente. Si se fuerza la detención, se reinicia el dispositivo, se instala una actualización de la aplicación o se desinstala, se perderán. Puede crear BroadcastReceivers
para algunas de esas situaciones para recrear sus alarmas.
Además, setInexactRepeating
es exactamente eso: inexacto. Cuando la alarma se dispara depende de la implementación y no se puede predecir con precisión.
También he usado el Servicio de Alarma en mi proyecto para tareas preparatorias en 6 o 7 minutos. Y está funcionando bien en todos los teléfonos.
He hecho un servicio de alarma como este:
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;
import android.util.Log;
public class MyAlarmService {
private static PendingIntent resetAlarm;
private static String TAG="CellPoliceChildGPSAlarmService";
private static AlarmManager am;
public static void start(Context context) {
try {
// We want the alarm to go off 30 seconds from now.
long firstTime = SystemClock.elapsedRealtime();
// Create an IntentSender that will launch our service, to be scheduled with the alarm manager.
//resetAlarm = PendingIntent.getService(context, 0, new Intent(context, Get_NonRootDetails.class), 0);
resetAlarm = PendingIntent.getService(context, 0, new Intent(context, CallNonRBackgroundService.class), 0);
// Schedule the alarm!
am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Log.i(TAG, firstTime+"");
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, 10*1000*60, resetAlarm);
}
catch (Exception e) {
Log.v("CellInfo", "Exception while start the MyAlarmService at: " + e.getMessage());
}
}
public static void stop(Context context) {
try {
// When interval going to change from web services
am.cancel(resetAlarm);
}
catch (Exception e) {
Log.v("CellInfo", "Exception while start the MyAlarmService at: " + e.getMessage());
}
}
}
He llamado o empiezo así;
MyAlarmService.start(SplashActivity.this);
Con permiso en Manifiesto:
<uses-permission android:name="android.permission.WAKE_LOCK">
<service
android:name="com.secure.DataCountService"
android:enabled="true" >
<intent-filter>
<action android:name="com.secure.MyService" />
</intent-filter>
</service>
Para las notificaciones también utilicé intenciones pendientes como;
Intent notificationIntent = new Intent(context, DashBoardActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, PushNotificationUtils.notiMsg, pendingIntent);
notification.flags |= notification.FLAG_AUTO_CANCEL;
Trate de colocar AlarmManager en el servicio en segundo plano.
Verifique si la aplicación está en estado detenido. Cuando la aplicación está en estado detenido, no recibirá ninguna alarma o evento.
Además, creo que podría ser un problema de firmware / OS específico del fabricante / OEM. Para verificar si la alarma se está programando realmente, use la alarma de dumpys de adb shell y compruebe si la alarma de su aplicación se ha programado realmente.
Para verificar si está en estado detenido, use el siguiente comando:
El paquete adb shell dumpsys "com.package.name" y verifica "detenido = verdadero"
Para saber más sobre el estado detenido consulte:
Launch controls on stopped applications
Starting from Android 3.1, the system''s package manager keeps track of applications that are in a stopped state and provides a means of controlling their launch from background processes and other applications.
Note that an application''s stopped state is not the same as an Activity''s stopped state. The system manages those two stopped states separately.
The platform defines two new intent flags that let a sender specify whether the Intent should be allowed to activate components in stopped application.
FLAG_INCLUDE_STOPPED_PACKAGES — Include intent filters of stopped applications in the list of potential targets to resolve against.
FLAG_EXCLUDE_STOPPED_PACKAGES — Exclude intent filters of stopped applications from the list of potential targets.
When neither or both of these flags is defined in an intent, the default behavior is to include filters of stopped applications in the list of potential targets.
Note that the system adds FLAG_EXCLUDE_STOPPED_PACKAGES to all broadcast intents. It does this to prevent broadcasts from background services from inadvertently or unnecessarily launching components of stoppped applications. A background service or application can override this behavior by adding the FLAG_INCLUDE_STOPPED_PACKAGES flag to broadcast intents that should be allowed to activate stopped applications.
Applications are in a stopped state when they are first installed but are not yet launched and when they are manually stopped by the user (in Manage Applications).
Tenga en cuenta que el estado detenido es diferente del proceso de la aplicación que no se está ejecutando.
Try this it works when activity is not running..
Calendar calendar = Calendar.getInstance();
long timemills = calendar.getTimeInMillis();
Intent myIntent = new Intent(this, TimeChangeReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, timemills, pendingIntent);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, timemills,
10000, pendingIntent);