2010-08-27 3 views
1

Я пытаюсь создать систему аутентификации, которая выведет окно входа в систему, если устройство выключено (SCREEN_OFF) для более чем INTERVAL.Leaked Intent & AlarmManager

Я зарегистрировал BroadcastReceiver слушать SCREEN_ON/OFF событий в OnCreate() из спускаемых деятельности:

/* Listen to Screen On & Off events */ 
    IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON); 
    filter.addAction(Intent.ACTION_SCREEN_OFF); 
    BroadcastReceiver screenOnOff = new ScreenOnOff(); 
    registerReceiver(screenOnOff, filter); 

ScreenOnOff - это BroadcastReceiver, который среди прочего делает:

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


mAuthenticationIntent = PendingIntent.getActivity(context, 0, 
    new Intent(context, AuthenticationActivity.class), 0); 

String action = intent.getAction(); 

if (action.equals(Intent.ACTION_SCREEN_OFF)) { 
    AlarmManager mAlarmManager = (AlarmManager) context 
    .getSystemService(context.ALARM_SERVICE); 
    mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, System 
    .currentTimeMillis() 
    + interval, mAuthenticationIntent); 

    Log.d(LOG_TAG, "Alarm Set!"); 
    } 

При срабатывании будильника, программа падает:

08-27 19:18:02.207: ERROR/ActivityThread(3165): Activity com.artoo.ArtooSlateActivity has leaked IntentReceiver [email protected] that was originally registered here. Are you missing a call to unregisterReceiver()? 
08-27 19:18:02.207: ERROR/ActivityThread(3165): android.app.IntentReceiverLeaked: Activity com.artoo.ArtooSlateActivity has leaked IntentReceiver [email protected] that was originally registered here. Are you missing a call to unregisterReceiver()? 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at android.app.ActivityThread$PackageInfo$ReceiverDispatcher.<init>(ActivityThread.java:939) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at android.app.ActivityThread$PackageInfo.getReceiverDispatcher(ActivityThread.java:734) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:791) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at android.app.ContextImpl.registerReceiver(ContextImpl.java:778) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at android.app.ContextImpl.registerReceiver(ContextImpl.java:772) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:318) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at com.artoo.ArtooSlateActivity.onCreate(ArtooSlateActivity.java:50) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3815) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at android.app.ActivityThread.access$2400(ActivityThread.java:125) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2037) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at android.os.Handler.dispatchMessage(Handler.java:99) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at android.os.Looper.loop(Looper.java:123) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at android.app.ActivityThread.main(ActivityThread.java:4627) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at java.lang.reflect.Method.invokeNative(Native Method) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at java.lang.reflect.Method.invoke(Method.java:521) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
08-27 19:18:02.207: ERROR/ActivityThread(3165):  at dalvik.system.NativeStart.main(Native Method) 

Любая помощь будет оценена по достоинству.

Спасибо, Самир

ответ

1

Поскольку вы регистрируете приемник динамически система знает, что происходит утечка памяти, потому что вы никогда не называйте unregister на нем. Очевидно, что вы не хотите отменять регистрацию, потому что вам нужно прослушивать события SCREEN_ON/OFF.

Решение является зарегистрировать приемник в вашей Manifest.xml

Базового класса для кода, который будет получать намерения посланных sendBroadcast(). Вы можете динамически регистрировать экземпляр этого класса с помощью Context.registerReceiver() или статически публиковать реализацию через тег в вашем AndroidManifest.xml. Примечание. Если вы регистрируете ресивер в своей реализации Activity.onResume(), его следует отменить в Activity.onPause(). (Вы не будете получать намерения при приостановке, и это сократит ненужные системные издержки). Не разрегистрировать в Activity.onSaveInstanceState(), потому что это не будет вызываться, если пользователь перемещается назад в стеке истории

+0

Я согласен, за исключением того, что 'ACTION_SCREEN_OFF', и, вероятно,' ACTION_SCREEN_ON', не может быть использован зарегистрированными манифестами «BroadcastReceivers»: http://code.google.com/p/android/issues/detail?id=10735 – CommonsWare

+0

Точно, так что мне делать и как реализовать свой код? –