2011-02-19 9 views
6

W mojej aplikacji, w metodzie onCreate() głównego działania tworzę blokadę wybudzania, aby procesor działał dalej, jeśli telefon będzie działał standb/screen wyłączy się.Android - blokada budzenia nie jest poprawnie pobierana, aplikacja musi działać w trybie gotowości

Również w metodzie onCreate mam zamiar stworzyć usługę korzystającą z akcelerometru. Ta usługa musi być ciągle uruchomiona, gdy aplikacja jest otwarta i monitorować wartości akcelerometru (wiem, że to nie jest dobre dla baterii, ale potrzebuję jej do tego). Oto mój kod w tej chwili i usługa zaczyna się dobrze.

public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE); 
     PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Howaya"); 
     wl.acquire(); 

     if (appStart == true) 
     { 
      Intent AccelService = new Intent(this, Accelerometer.class); 
      AccelService.putExtra("unreg", false); 
      startService(AccelService); 
     } 
     appStart = false; 
    } 

Mam następujące uprawnienia ustawione w moim manifestu -

<uses-permission android:name="android.permission.WAKE_LOCK" /> 

próbowałem to z różnymi zamkami - wym ekranu i pełnej jasności bezskutecznie też. Moje wyjście na LogCat jest tutaj -

F/PowerManager(15628): android.util.Log$TerribleFailure: WakeLock finalized while still held: Howaya 
F/PowerManager(15628): at android.util.Log.wtf(Log.java:260) 
F/PowerManager(15628): at android.util.Log.wtf(Log.java:239) 
F/PowerManager(15628): at android.os.PowerManager$WakeLock.finalize(PowerManager.java:329) 
F/PowerManager(15628): at dalvik.system.NativeStart.run(Native Method) 

Widziałem ludzi, którzy mówią, że częściowe wakelocks nie działają tak jak powinny to zrobić, jak ten link Google standby error page ale ten został wydany w ubiegłym roku i zamknięty więc nie wiem Czy to możliwe, czy ktoś może tu pomóc? Mam HTC Desire w odniesieniu do tego ostatniego punktu, dzięki.

Odpowiedz

2

W mojej aplikacji w sposobie onCreate() głównego aktywności Tworzę blokadę wake tak, że procesor będzie nadal działać, gdy telefon jest długa Stan gotowoÊci/wyłączenie ekranu.

Proszę użyć android:keepScreenOn na jednym z widżetów w swoim układzie. To znacznie bezpieczniejsze dla czynności niż ręczne radzenie sobie z WakeLock. Dodatkowo, nie potrzebujesz wtedy uprawnienia WAKE_LOCK, IIRC.

moje wyjście na LogCat jest tutaj

To jest błąd, ponieważ nigdy nie puścisz WakeLock. Proszę nie przeciekać WakeLocks.

Teraz udało Ci się napisać całą tę prozę i uwzględnić wszystkie te aukcje, a ty zapomniałaś o jednej rzeczy: mówi nam, jakie jest twoje pytanie:. Jest to dość ważny element na stronie z pytaniami i odpowiedziami, np. StackOverflow. I nie, "czy ktoś może tu pomóc?" nie liczy się jako pytanie, gdy nigdy nie definiujesz "pomocy", której szukasz.

+0

OK przepraszam, jeśli byłem niejasny i dziękuję za odpowiedź. Moje pytanie brzmiało: w jaki sposób mogę uruchomić funkcję wakelock na moim telefonie, aby moja aplikacja działała, gdy ekran jest nadal wyłączony, ponieważ kod, którego używam powyżej, nie działa. Wolałbym nie mieć ekranu, żeby nie marnował tyle baterii i nie musiał używać widżetu, na wypadek, gdyby zdecydowałem się umieścić go na rynku (wtedy inni użytkownicy musieliby użyć widżetu) – bobby123

+1

@ bobby123 : Działanie nie może logicznie potrzebować częściowego 'WakeLock'. Usługa * może wymagać częściowego WakeLock, ale nie działania, którego jedynym celem jest wyświetlanie rzeczy na ekranie. Tak więc albo wyrzuć 'WakeLock' z działania i do usługi (dopasuj logikę biznesową do dopasowania), albo użyj' android: keepScreenOn'. Zdobądź 'WakeLock' w' onCreate() 'swojej usługi i zwolnij go w' onDestroy() '. Użyj 'startForeground()', aby twoja usługa nie była nuked i dać użytkownikowi łatwy sposób, aby dostać się do działania, aby zatrzymać usługę. – CommonsWare

+0

To właśnie chciałem wiedzieć, dzięki. Przeniosę blokadę wake'a do serwisu, bo tego naprawdę potrzebuję. Mam przycisk menu, aby użytkownik mógł zakończyć usługę w dowolnym momencie. Jeszcze jedno pytanie, czy wiesz, czy metoda onSensorChanged() dla akcelerometru nadal działa, gdy jest pod częściową blokadą wybudzania, czy jest to nadal problem z Google? – bobby123

9

Problem występuje, ponieważ obiekt WakeLock jest lokalną zmienną o ustalonym zakresie w metodzie OnCreate. Po wykonaniu metody - obiekt WakeLock nie jest już odwoływany - w związku z tym kwalifikuje się do czyszczenia pamięci. Jeśli pojawi się Dalvik GC - obiekt jest gotowy do sfinalizowania - a wewnętrzny kod finalizera ostrzega Cię, że WakeLock jest nadal trzymany - i aktywny - ale zostanie GC. Musisz zdobyć nowy obiekt WakeLock i przypisać go do pola klasy typu WakeLock w klasie pochodnej Twoja aktywność. Przeczytaj o programowaniu obiektowym i Garbage Collector - zrozumiesz problem.

0

Jak powiedział @Michal P, nabędziesz wakelock w metodzie onCreate, ale nigdy go nie zwolnisz.

Gdy GC przeskanuje ten obiekt z odniesieniem zerowym, wywołaj domyślną metodę finalizacji, ale w rzeczywistości jest ona aktywna.

@Override 
    protected void finalize() throws Throwable { 
     synchronized (mToken) { 
      if (mHeld) { 
       Log.wtf(TAG, "WakeLock finalized while still held: " + mTag); 
       Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, mTraceName, 0); 
       try { 
        mService.releaseWakeLock(mToken, 0); 
       } catch (RemoteException e) { 
       } 
      } 
     } 
    } 
Powiązane problemy