Czy istnieje natywny sposób na Androida, aby uzyskać odniesienie do aktualnie działającego działania z usługi?
Mam usługę działającą w tle i chciałbym zaktualizować moją bieżącą aktywność, gdy wystąpi zdarzenie (w usłudze). Czy jest na to łatwy sposób (taki jak ten, który zasugerowałem powyżej)?
android
service
android-activity
Jerzy
źródło
źródło
Odpowiedzi:
Możesz nie być właścicielem „aktualnie działającego działania”.
Intent
do działania - oto przykładowy projekt demonstrujący ten wzórPendingIntent
(np. PrzezcreatePendingResult()
) wywołaną przez usługębindService()
, a usługa wywołała metodę zdarzenia dla tego obiektu wywołania zwrotnego / obiektu nasłuchiwaniaIntent
do działania, z niskim priorytetemBroadcastReceiver
jako kopię zapasową (aby podnieść,Notification
jeśli aktywność nie jest wyświetlana na ekranie) - oto post na blogu z większą ilością tego wzoruźródło
instanceof
czeków lub refaktoryzacji działań w celu udostępnienia wspólnej nadklasy lub interfejsu. A jeśli zamierzasz refaktoryzować działania, równie dobrze możesz to zrobić w sposób, który lepiej pasuje do frameworka i obejmuje więcej scenariuszy, takich jak brak aktywności. # 4 to prawdopodobnie najmniej pracochłonna i najbardziej elastyczna.Aktualizacja : nie działa już w przypadku działań innych aplikacji od Androida 5.0
Oto dobry sposób na zrobienie tego za pomocą menedżera aktywności. Zasadniczo dostajesz runningTasks od menedżera aktywności. Zawsze najpierw zwróci aktualnie aktywne zadanie. Stamtąd możesz uzyskać najwyższą Aktywność.
Przykład tutaj
Istnieje prosty sposób na uzyskanie listy uruchomionych zadań z usługi ActivityManager. Możesz zażądać maksymalnej liczby zadań uruchomionych na telefonie, a domyślnie aktualnie aktywne zadanie jest zwracane jako pierwsze.
Gdy już to zrobisz, możesz uzyskać obiekt ComponentName, żądając topActivity z listy.
Oto przykład.
Będziesz potrzebować następującego pozwolenia na swój manifest:
źródło
As of LOLLIPOP, this method is no longer available to third party applications: the introduction of document-centric recents means it can leak person information to the caller. For backwards compatibility, it will still return a small subset of its data: at least the caller's own tasks, and possibly some other tasks such as home that are known to not be sensitive.
Ostrzeżenie: naruszenie Google Play
Google zagroził usunięciem aplikacji ze Sklepu Play, jeśli będą korzystać z usług ułatwień dostępu w celach niedostępności. Jednakże, jest to podobno ponownie rozpatrzona .
Użyj
AccessibilityService
AccessibilityService
.onAccessibilityEvent
wywołaniu zwrotnym sprawdź typ zdarzenia, aby określić, kiedy zmienia się bieżące okno.TYPE_WINDOW_STATE_CHANGED
PackageManager.getActivityInfo()
.Korzyści
GET_TASKS
pozwolenia.Niedogodności
AccessibilityService
, nie może nacisnąć przycisku OK, jeśli aplikacja umieściła nakładkę na ekranie. Niektóre aplikacje, które to robią, to Velis Auto Brightness i Lux. Może to być mylące, ponieważ użytkownik może nie wiedzieć, dlaczego nie może nacisnąć przycisku ani jak go obejść.AccessibilityService
Nie będą wiedzieć, bieżącej działalności, aż do pierwszej zmiany aktywności.Przykład
Usługa
AndroidManifest.xml
Połącz to ze swoim manifestem:
Informacje serwisowe
Umieść to w
res/xml/accessibilityservice.xml
:Włączanie usługi
Każdy użytkownik aplikacji będzie musiał wyraźnie włączyć opcję,
AccessibilityService
aby można było z niej korzystać. Zobacz odpowiedź StackOverflow, jak to zrobić.Pamiętaj, że użytkownik nie będzie mógł nacisnąć przycisku OK podczas próby włączenia usługi ułatwień dostępu, jeśli aplikacja umieściła na ekranie nakładkę, taką jak Velis Auto Brightness lub Lux.
źródło
settingsActivity
oyour.app.ServiceSettingsActivity
, więc należy zmienić na swojej własnej działalności ustawień dla usługi dostępności. Wydaje mi się, że i tak aktywność ustawień jest opcjonalna, więc usunąłem tę część z mojej odpowiedzi, aby uprościć.onAccessibilityEvent
nie otrzymuje żadnego zdarzenia, ale jeśli wyłączę i ponownie włączę usługę dostępności, usługa zostanie ponownie aktywowana ionAccessibilityEvent
zacznie działać.Można to zrobić przez:
Zaimplementuj własną klasę aplikacji, zarejestruj się w ActivityLifecycleCallbacks - w ten sposób zobaczysz, co się dzieje z naszą aplikacją. Przy każdym wznowieniu oddzwonienie przypisuje bieżącą widoczną aktywność na ekranie, a po wstrzymaniu usuwa przypisanie. Wykorzystuje metodę
registerActivityLifecycleCallbacks()
dodaną w API 14.W zgłoszeniu serwisowym
getApplication()
i rzuć go na nazwę klasy aplikacji (w tym przypadku App). Niż możesz zadzwonićapp.getActiveActivity()
- to da ci bieżącą widoczną Aktywność (lub zero, gdy żadna aktywność nie jest widoczna). Nazwę działania można uzyskać, dzwoniącactiveActivity.getClass().getSimpleName()
źródło
onActivityResumed()
,onActivityPaused()
igetActiveActivity()
zobaczyć jak to jest Callet, jeśli kiedykolwiek tak.activity
iactiveActivity
są takie same przed przypisaniemactiveActivity
zenull
aby uniknąć błędów z uwagi na przeplataną celu wywołującego metod cyklu życia różnych działań.Nie mogłem znaleźć rozwiązania, z którego nasz zespół byłby zadowolony, więc wprowadziliśmy własne. Używamy
ActivityLifecycleCallbacks
do śledzenia bieżącej aktywności, a następnie ujawniamy ją za pośrednictwem usługi:Następnie skonfiguruj kontener DI, aby zwracał instancję
MyApplication
dlaContextProvider
np(Zauważ, że implementacja
getCurrent()
jest pominięta w powyższym kodzie. Jest to po prostu zmienna statyczna ustawiona w konstruktorze aplikacji)źródło
activity
icurrentActivity
są takie same przed przypisaniemcurrentActivity
zenull
aby uniknąć błędów z uwagi na przeplataną celu wywołującego metod cyklu życia różnych działań.Posługiwać się
ActivityManager
Jeśli chcesz tylko znać aplikację zawierającą bieżącą aktywność, możesz to zrobić za pomocą
ActivityManager
. Technika, której możesz użyć, zależy od wersji Androida:ActivityManager.getRunningTasks
( przykład )ActivityManager.getRunningAppProcesses
( przykład )Korzyści
Niedogodności
ActivityManager.RunningAppProcessInfo.processState
Przykład (na podstawie kodu KNaito )
Oczywisty
Dodaj
GET_TASKS
uprawnienie doAndroidManifest.xml
:źródło
Używam tego do moich testów. Jest to API> 19, ale tylko dla działań Twojej aplikacji.
źródło
Użyj tego kodu dla API 21 lub nowszego. Działa to i daje lepszy wynik w porównaniu do innych odpowiedzi, doskonale wykrywa proces pierwszego planu.
źródło
Oto moja odpowiedź, która działa dobrze ...
Powinieneś być w stanie uzyskać bieżącą Aktywność w ten sposób ... Jeśli zbudujesz aplikację z kilkoma Aktywnościami z wieloma fragmentami i chcesz śledzić, jaka jest twoja Aktywność, zajmie to jednak dużo pracy. Moim senario było to, że mam jedną Aktywność z wieloma Fragmentami. Mogę więc śledzić bieżącą aktywność za pośrednictwem obiektu aplikacji, który może przechowywać cały bieżący stan zmiennych globalnych.
Oto sposób. Kiedy zaczynasz swoją aktywność, przechowujesz ją przez Application.setCurrentActivity (getIntent ()); Ta aplikacja będzie go przechowywać. W klasie usług możesz po prostu zrobić jak Intent currentIntent = Application.getCurrentActivity (); getApplication (). startActivity (currentIntent);
źródło
Nie wiem, czy to głupia odpowiedź, ale rozwiązałem ten problem, przechowując flagę we wspólnych preferencjach za każdym razem, gdy wpisywałem funkcję onCreate () dowolnej aktywności, a następnie wykorzystałem wartość z preferencji ścinania, aby dowiedzieć się, co to jest aktywność na pierwszym planie.
źródło
Niedawno się o tym dowiedziałem. Z apis jako:
targetSdkVersion 26
ActivityManager.getCurrentActivity (kontekst)
Mam nadzieję, że to się przyda.
źródło
getCurrentActivity()
funkcji wActivityManager
klasie ( developer.android.com/reference/android/app/ActivityManager ). Zabawne, że ta funkcja nie istnieje:ActivityManager.isUserAMonkey()
.