2011-07-28 55 views
23

我想要在某個時間顯示一個活動。爲此,我使用AlarmManager。 當設備喚醒時它工作正常,但是如果它睡着了,它不會喚醒它。android AlarmManager沒有喚醒電話

我設定報警代碼:

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); 

我的廣播接收器:

@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)); 
} 
} 

此代碼不會喚醒該設備。但是,當我將它重新打開時,它們會顯示。我需要讓他們打開屏幕。你能幫我解決這個問題嗎?

+0

轉到您要在的onReceive啓動活動()。將其粘貼到該活動的onCreate()中 final Window 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

回答

55

我有一個類似的問題,解決方案是使用WakeLocker。這應該完成(最好是接收器中的第一件事),或者當收到警報時設備將醒來,但在context.startActivity(newIntent)之前將再次入睡;叫做。 (我還觀察到的行爲時不會發生,因此,它似乎有點武斷) 所以容易和快速的答案: 建立一個叫做WakeLocker這個源代碼的新類:

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; 
    } 
} 

和作爲第一件事在您的接收器電話WakeLocker.acquire(context);。 另外:一旦你的鬧鈴完成了,它也可以打電話給WakeLocker.release();

+2

非常感謝。現在,手機終於在指定的時間醒來。我也很喜歡WakeLocker類的靜態方法。 – Gabriel

+7

需要權限 http://developer.android.com/reference/android/os/PowerManager.html – Palani

+0

謝謝,這太好了。但直到我發現我的手機(華碩Zenfone Selfie)要求我明確允許應用程序被喚醒時,它纔會起作用。 – cpliu338

30

最有可能的是,鬧鐘正在喚醒設備。但是,AlarmManager廣播不會打開屏幕,並且在您的活動啓動之前設備可能會重新入睡。

您需要調用startActivity()之前收購onReceive()一個WakeLock,並釋放WakeLock用戶響應您的活動後。

+0

這是正確的答案。 ^^^ – user123321

+0

你測試過了嗎?屏幕也會打開,而無需獲取WakeLock – 2cupsOfTech

+0

@ 2cupsOfTech:「您測試過了嗎?」 - 是的。 「屏幕打開,而無需獲取WakeLock」 - AlarmManager廣播不會打開屏幕。如果沒有'WakeLock'(例如,使用'getService()'作爲PendingIntent',然後在服務中獲取'WakeLock')是不可靠的。它有時會起作用,而不是其他的。這就是爲什麼我發佈了'WakefulIntentService'以及爲什麼Google使用'WakefulBroadcastReceiver'跟蹤它。 – CommonsWare