Android - Dynamically Get the Current Activity in Foreground
Asked Answered
L

6

11

here is the situation:

  1. In a Thread an event is triggered.
  2. The current activity needs to be retrieved.
  3. Then a Dialog Box is created on that activity and shown.

Problems: As far as I've searched there is no way to retrieve the current activity in the foreground.

Extra info: This needs to be able to be handled in multiple activities. So, it can be popped-up in Activity-A or B or C.

Lotetgaronne answered 7/8, 2013 at 23:29 Comment(3)
possible duplicate of How to get any identifier of the topmost activity?Backpack
https://mcmap.net/q/89538/-how-to-get-current-foreground-activity-context-in-androidAmabil
Possible duplicate of How to get current foreground activity context in android?Enallage
K
16

I'm not sure if this is what you're looking for, but it seemed pretty straightforward. http://iamvijayakumar.blogspot.com/2011/09/get-current-activity-and-package-name.html

  ActivityManager am = (ActivityManager) this .getSystemService(ACTIVITY_SERVICE);
  List<RunningTaskInfo> taskInfo = am.getRunningTasks(1);
  ComponentName componentInfo = taskInfo.get(0).topActivity;
  Log.d(WebServiceHelper.TAG, "CURRENT Activity ::" + taskInfo.get(0).topActivity.getClassName()+"   Package Name :  "+componentInfo.getPackageName());

Hope this helps.

Kaneshakang answered 7/8, 2013 at 23:35 Comment(5)
It should be noted that you need to ask for android.permission.GET_TASKS for this to work.Coburn
Wondering if accessing that would cause app rejection?Betoken
Careful, this is deprecated since API 21 Lollipop.Misprision
Not only is this deprecated in Android 5, but [developer.android.com/reference/android/app/… documentation) implies it won't even work.Lanchow
Is there any other way above android 5.Trinitarianism
S
6

Plan A: taking your request literally

Step #1: Have the thread be managed by a service

Step #2: have the service send a message when the "even is triggered" -- LocalBroadcastManager, Square's Otto, greenrobot's EventBus, etc.

Step #3: Have each activity be set up to listen for that message when it is in the foreground

Step #4: Have the activity display the dialog upon receipt of the message


Plan B: same visual result

Step #1: Have the thread be managed by a service

Step #2: Have the service call startActivity() on a dialog-themed activity

Step #3: There is no step #3

Spiculum answered 7/8, 2013 at 23:34 Comment(7)
Hooray for step 2 (in both plans)! But why is step 1 (using a service) important, vs. using an AsyncTask for example?Tangleberry
@LarsH: If the background work will go on long enough that you do not know what the foreground UI is (or even if it is in your own app), you probably want a service, just to signal to Android that you are doing that background work, so your process can live a bit longer.Spiculum
Step 2 in Plan B assumes that one knows for which activity startActivity() is to be called. This is the crux of the problem. I want the Activity on the top of my task to be started. How to get hold of that Activity?Consistency
@RaghubanshMani: In your case, you use Plan A. Have your activities register for the event in onStart() and unregister in onStop(). Whichever activity is presently visible will process the event.Spiculum
Having each Activity register and unregister seems a bit repetitive and wasteful, but, I guess there is no avoiding it here. Putting it into a BaseActivity superclass feels abusing.Consistency
@RaghubanshMani: Registering with an event bus is fairly cheap, and if you happen to have a BaseActivity already, registering in there would seem to be a good plan. I don't know that I would necessarily introduce a common superclass just for two lines of code, but if you already have such a superclass, use it.Spiculum
I do have a BaseActivity superclass. But I am hesitant to put such code there. My purpose for having such base classes is to provide common helper methods which all the sub-classes will use, like, fragment transaction, resource access, etc. I don't like putting behavioral logic there because I rarely open such files. It could easily become an unwanted feature in a new sub-class. It's just a preference for me - keep behavior code in front of eyes.Consistency
E
0

You can achieve this using a custom broadcast receiver. You can define a broadcast receiver in your thread and write the receiver in different activities. And from your thread you can decide which activity to send broadcast.

In the receiver, you can show the dialog.

Elizbeth answered 7/8, 2013 at 23:38 Comment(0)
M
0

You may do that by extending Activity and Application and having methods that get and set the current viewed Activity reference as an Application level variable. Try this approach: How to get current foreground activity context in android?.

Mcgruter answered 7/8, 2013 at 23:39 Comment(5)
Hehe, that approach is completely equivalent to storing current Activity in a static variable.Zacharyzacherie
Nope, the top scoring answer doesn't use a static variableMcgruter
No but it uses the Application to reference an Activity. Application is never garbage collected and therefore Activity is never garbage collected when referenced from Application. That is equivalent to using static variables since they are referenced from their Class object which is as well never garbage collected.Zacharyzacherie
Yeah, I wouldn't do it completely the samesince there is a cleaner and memory efficient way to complete the same task. But the variables are nullified onPause so it should be garbage collected stillMcgruter
If you null them in onPause you could as well use a static variable :) If you can't guarantee that this happens you get the leak either way. Only thing you can (and maybe should do anyways) is to keep a WeakReference to them. It's guaranteed they they don't get GC'd until after the Activity hits onDestroy.Zacharyzacherie
S
0

Use Face book's stetho package is safest and simplest way for me (and no complaints from other team members that "it's hacky we won't approve!" thing...

Just as simple as:

ActivityTracker.get().tryGetTopActivity();

Softy answered 14/11, 2016 at 22:57 Comment(0)
P
0

just like @Xian Zhang said, using Facebook stetho lib is working for me

ActivityTracker.get().tryGetTopActivity()?.localClassName

If your activity is within the package ui , the output be like

    ui.YourActivityName

your app package name will not be included

Pyknic answered 20/9, 2019 at 2:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.