2011-07-28 8 views
23

Chcę, aby aktywność była wyświetlana o określonej godzinie. Do tego używam programu AlarmManager. Działa dobrze, gdy urządzenie nie śpi, ale nie budzi go, jeśli śpi.Android AlarmManager nie budzi telefonu

Mój kod do ustawiania alarmu:

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

Mój odbiornik transmisji:

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

Ten kod nie obudzić urządzenie. Jednak po ponownym włączeniu są wyświetlane. Muszę sprawić, żeby włączali ekran. Czy możesz mi pomóc w tym problemie?

+0

iść do działalności, które chcesz rozpocząć w onReceive(). Wklej to w onCreate() tego działania final Okno 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

Odpowiedz

55

Miałem podobny problem, a rozwiązaniem było zastosowanie WakeLocker. To powinno być zrobione (najlepiej jako pierwsza rzecz w odbiorniku), lub urządzenie będzie się budzić po otrzymaniu alarmu, ale zasnął ponownie przed context.startActivity(newIntent); jest nazywany. (Mam również obserwowane zachowanie, gdy tak się nie dzieje, więc wydaje się być nieco arbitralne) więc łatwe i szybkie odpowiedzi: Dodać nową klasę o nazwie WakeLocker z tym kodem źródłowym:

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

i w odbiorniku zadzwoń pod numer WakeLocker.acquire(context); jako pierwszą rzecz. Dodatek: byłoby również fajnie zadzwonić pod numer WakeLocker.release(); po alarmie.

+2

Dziękuję bardzo. Teraz telefon w końcu budzi się o określonej godzinie. Bardzo podoba mi się także statyczne podejście klasy WakeLocker. – Gabriel

+7

wymaga pozwolenia http://developer.android.com/reference/android/os/PowerManager.html – Palani

+0

Dziękuję, to świetnie. Ale nadal nie działało, dopóki nie stwierdziłem, że mój telefon (Asus Zenfone Selfie) wymaga od mnie jawnego zezwolenia na przebudzenie aplikacji. – cpliu338

30

Najprawdopodobniej alarm budzi urządzenie. Jednak transmisje AlarmManager nie włączają ekranu, a urządzenie może z powrotem zasnąć przed rozpoczęciem aktywności.

Trzeba będzie nabyć WakeLock w onReceive() przed wywołaniem startActivity() i zwolnij że WakeLock gdy użytkownik odpowiada na swojej działalności.

+0

To jest poprawna odpowiedź. ^^^ – user123321

+0

testowałeś to? Ekran włącza się również bez potrzeby nabywania funkcji WakeLock – 2cupsOfTech

+0

@ 2cupsOfTech: "czy to przetestowałeś?" -- tak. "Ekran również się włącza bez potrzeby przejęcia WakeLocka" - transmisje 'AlarmManager' nie włączają się na ekranie. Bez 'WakeLock' (np. Użycie' getService() 'jako' PendingIntent', a następnie przechwytywanie 'WakeLock' w usłudze) jest niewiarygodne. To zadziała czasem, a nie inne. Właśnie dlatego wydałem 'WakefulIntentService' i dlaczego Google podążył za tym' WakefulBroadcastReceiver'. – CommonsWare