Is there a native android way to get a reference to the currently running Activity from a service?
I have a service running on the background, and I would like to update my current Activity when an event occurs (in the service). Is there a easy way to do that (like the one I suggested above)?
Here is my answer that works just fine...
You should be able to get current Activity in this way... If you structure your app with a few Activities with many fragments and you want to keep track of what is your current Activity, it would take a lot of work though. My senario was I do have one Activity with multiple Fragments. So I can keep track of Current Activity through Application Object, which can store all of the current state of Global variables.
Here is a way. When you start your Activity, you store that Activity by Application.setCurrentActivity(getIntent()); This Application will store it. On your service class, you can simply do like Intent currentIntent = Application.getCurrentActivity(); getApplication().startActivity(currentIntent);
You may not own the "currently running Activity".
Intent
to the activity -- here is a sample project demonstrating this patternPendingIntent
(e.g., viacreatePendingResult()
) that the service invokesbindService()
, and have the service call an event method on that callback/listener objectIntent
to the activity, with a low-priorityBroadcastReceiver
as backup (to raise aNotification
if the activity is not on-screen) -- here is a blog post with more on this patternWarning: Google Play violation
Google has threatened to remove apps from the Play Store if they use accessibility services for non-accessibility purposes. However, this is reportedly being reconsidered.
Use an
AccessibilityService
AccessibilityService
.onAccessibilityEvent
callback, check for theTYPE_WINDOW_STATE_CHANGED
event type to determine when the current window changes.PackageManager.getActivityInfo()
.Benefits
GET_TASKS
permission.Disadvantages
AccessibilityService
, they can't press the OK button if an app has placed an overlay on the screen. Some apps that do this are Velis Auto Brightness and Lux. This can be confusing because the user might not know why they can't press the button or how to work around it.AccessibilityService
won't know the current activity until the first change of activity.Example
Service
AndroidManifest.xml
Merge this into your manifest:
Service Info
Put this in
res/xml/accessibilityservice.xml
:Enabling the Service
Each user of the app will need to explicitly enable the
AccessibilityService
in order for it to be used. See this StackOverflow answer for how to do this.Note that the user won't be able to press the OK button when trying to enable the accessibility service if an app has placed an overlay on the screen, such as Velis Auto Brightness or Lux.
I could not find a solution that our team would be happy with so we rolled our own. We use
ActivityLifecycleCallbacks
to keep track of current activity and then expose it through a service:Then configure your DI container to return instance of
MyApplication
forContextProvider
, e.g.(Note that implementation of
getCurrent()
is omitted from the code above. It's just a static variable that's set from the application constructor)I'm using this for my tests. It's API > 19, and only for activities of your app, though.