2011-07-28 11 views
23

Quiero que se muestre una actividad en un momento determinado. Para esto, estoy usando AlarmManager. Funciona bien cuando el dispositivo está encendido, pero no lo activa si está dormido.android AlarmManager no despierta teléfono

Mi código para configurar la alarma:

Calendar alarmTime = Calendar.getInstance(); 
alarmTime.set(Calendar.HOUR_OF_DAY, alarm.hour); 
alarmTime.set(Calendar.MINUTE, alarm.minute); 
alarmTime.set(Calendar.SECOND, 0); 

if (alarmTime.before(now)) 
    alarmTime.add(Calendar.DAY_OF_MONTH, 1); 

Intent intent = new Intent(ctxt, AlarmReceiver.class); 
intent.putExtra("alarm", alarm); 
PendingIntent sender = PendingIntent.getBroadcast(ctxt, alarm.id, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
alarmManager.set(AlarmManager.RTC_WAKEUP, alarmTime.getTimeInMillis(), sender); 

Mi difusión receptor:

@Override 
public void onReceive(Context context, Intent intent) { 
    try { 

Bundle bundle = intent.getExtras(); 
final Alarm alarm = (Alarm) bundle.getSerializable("alarm"); 

Intent newIntent; 
if (alarm.type.equals("regular")) { 
    newIntent = new Intent(context, RegularAlarmActivity.class); 
} else if (alarm.type.equals("password")) { 
    newIntent = new Intent(context, PasswordAlarmActivity.class); 
} else if (alarm.type.equals("movement")) { 
    newIntent = new Intent(context, MovementAlarmActivity.class); 
} else { 
    throw new Exception("Unknown alarm type"); 
} 
    newIntent.putExtra("alarm", alarm); 
    newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    context.startActivity(newIntent); 

} catch (Exception e) { 
    Toast.makeText(context, "There was an error somewhere, but we still received an alarm", Toast.LENGTH_SHORT).show(); 
    Log.e("AlarmReceiver", Log.getStackTraceString(e)); 
} 
} 

Este código no se despierta el dispositivo. Sin embargo, cuando lo vuelvo a abrir, se muestran. Necesito hacer que enciendan la pantalla. ¿Puedes ayudarme con este problema?

+0

en la actividad en la que desea iniciar en OnReceive(). Pegue esto en onCreate() de esa Actividad final Ventana win = getWindow(); win.addFlags (WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); win.addFlags (WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); – Junaid

Respuesta

55

Tuve un problema similar y la solución fue utilizar WakeLocker. Eso se debe hacer (preferiblemente como la primera cosa en el receptor), o el dispositivo se despertará cuando se reciba la alarma, pero se dormirá nuevamente antes de context.startActivity(newIntent); se llama. (También he observado comportamiento cuando eso no ocurre, por lo que parece ser un poco arbitraria) Así que la respuesta fácil y rápida: hacer una nueva clase llamada WakeLocker con este código fuente:

package mypackage.test; 

import android.content.Context; 
import android.os.PowerManager; 

public abstract class WakeLocker { 
    private static PowerManager.WakeLock wakeLock; 

    public static void acquire(Context ctx) { 
     if (wakeLock != null) wakeLock.release(); 

     PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE); 
     wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | 
       PowerManager.ACQUIRE_CAUSES_WAKEUP | 
       PowerManager.ON_AFTER_RELEASE, MainActivity.APP_TAG); 
     wakeLock.acquire(); 
    } 

    public static void release() { 
     if (wakeLock != null) wakeLock.release(); wakeLock = null; 
    } 
} 

y en su receptor llame al WakeLocker.acquire(context); como la 1ra cosa. Extra: también sería bueno llamar al WakeLocker.release(); una vez que la alarma haya hecho su trabajo.

+2

Muchas gracias. Ahora, el teléfono finalmente se despierta a la hora especificada. También me gusta mucho el enfoque estático de la clase WakeLocker. – Gabriel

+7

requiere permiso http://developer.android.com/reference/android/os/PowerManager.html – Palani

+0

Gracias, eso es genial. Pero aun así no funcionó hasta que descubrí que mi teléfono (Asus Zenfone Selfie) requería que permitiera explícitamente que la aplicación se despertara. – cpliu338

30

Lo más probable es que la alarma esté despertando el dispositivo. Sin embargo, las transmisiones AlarmManager no encenderán la pantalla, y es posible que el dispositivo se vuelva a quedar dormido antes de que comience su actividad.

Usted tendrá que adquirir una WakeLock en onReceive() antes de llamar startActivity() y liberar esa WakeLock después de que el usuario responde a su actividad.

+0

Esta es la respuesta correcta. ^^^ – user123321

+0

has probado esto? La pantalla también se enciende sin necesidad de adquirir WakeLock – 2cupsOfTech

+0

@ 2cupsOfTech: "¿Has probado esto?" - si. "La pantalla también se enciende sin necesidad de adquirir WakeLock" - Las transmisiones 'AlarmManager' no encienden la pantalla. Sin un 'WakeLock' (por ejemplo, usar' getService() 'como' PendingIntent', y luego tomar 'WakeLock' en el servicio) no es confiable. Funcionará a veces y no a otros. Es por eso que lancé el 'WakefulIntentService' y por qué Google siguió con el' WakefulBroadcastReceiver'. – CommonsWare

Cuestiones relacionadas