I have a service and its behavior must change when topmost Activity changes. Say, Activity A is active and then service starts some kind of processing. This processing must stop when Activity A is no longer visible: user pressed "Back", "Home" or did anything else that makes Activity A invisible. This Activity A must not be aware of the service -- i.e. it must not have to explicitly inform the Service that it is going away.
In the nutshell, is there a way to:
Get any kind of identification (object reference, class name, ID, etc.) of the topmost Activity,
Receive notification when topmost Activity changes?
P.S. This may sound like malware behavior, but it is not! It is legitimate use-case!
Edit: Activities are not in my application. They can be just about anything -- browser, maps app, settings, etc.
This top part is outdated. See bottom for answer.
I'm assuming you're referring to Activities within your own application:
All Activities call onResume() when coming to the foreground and onPause() when leaving the foreground. Simply override this method with your functionality (be sure to call super.onResume() and super.onPause() respectively!).
As for the identifier, perhaps you could make your Service have a static method that is called by an Activity coming to the foreground (in onResume()), supplying a reference to itself, its class, some arbitrary ID, etc.
Reference: http://developer.android.com/reference/android/app/Activity.html
Edit:
You can access the top Activity's identity via ActivityManager -> running tasks -> ComponentName. Be sure to declare <uses-permission android:name="android.permission.GET_TASKS" /> in your manifest.
Context context = someArbitraryContext;
ActivityManager am = (ActivityManager) context.
getSystemService(Activity.ACTIVITY_SERVICE);
String packageName = am.getRunningTasks(1).get(0).topActivity.getPackageName();
String className = am.getRunningTasks(1).get(0).topActivity.getClassName();
As for getting a notification, you'll probably have to just check the top Activity every x milliseconds.
Create a baseActivity and extends all other Activities from baseActivity, in onResume save Current Activity in a public static Filed in a Global class (in my case extends Application)
public class baseActivity extends Activity {
#Override
protected void onResume() {
super.onResume();
Global.Activity = this;
}
}
Other Activities
public class mainActivity extends baseActivity {
// You Can Use Global.Activity Everywhere ! , Even in a Object Extended Class
}
Related
I'm extending the Application class for my additional custom need. And I'm calling a method inside that. As the expected behaviour, it is getting invoked for type of Android components(Activity, Service, Broadcast receiver, etc.,) But I want that too be invoked only on Activity. Is that any other way to overcome this problem ?
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
// the below method needs to invoked only for service
// but now called for all application components
myCustomMethod();
}
....
}
But I want that too be invoked only on Activity.
Can't be done. The Application instance will run if one component of your Application is open.
You need to do the customized stuff in another class and open it just when the instance of your desire component is open.
just add your code to onCreate method of your entry-point activity. If you want it to be called once per session - add two int keys to your shared preferences - app_launch_count and method_invoke_count. Increment first on App's onCreate and check the second in your Activity's onCreate if first greater then invoke the method :)
Move myCustomMethod() into the activity. An Application has no way of knowing what triggered the creation of its process.
Or, use registerActivityLifecycleCallbacks() on Application to register an ActivityLifecycleCallbacks object, and put your myCustomMethod() logic in onActivityCreated(). This requires a minSdkVersion of 14 or higher. That will tell you when each activity is created after your process is instantiated — if you only care about the first one, you would have to unregister the callbacks in your onActivityCreated() implementation.
Is there a way to get a root view of one activity from another lets say there are two activity A and B i want root view of activity A from B.please Help
Edit: I am Trying to make change in Main Activity from Preference Activity for ex i want to change the text of TextView in Main Activity as soon as i select a checkboxpreference from preference activity.
A stopped, or hidden activity may no longer be present, to free up resources. It is not a good idea to reference objects from other Activities.
To send an event/data from one Activity to another Activity you may use:
Start newer activity using startActivityForResult(). And get results back via onActivityResult().
Share some data is a third object, accessible to all activities. Most likely a singleton or Application class.
Use EventBus and post sticky events. New subscribers will automatically get these events. This method works for all kinds of objects, not just activities.
I'm not sure what you would need this for, it sounds a little dangerous, but the root view probably won't exist without running first, but you MAY be able to get the root view while it's running and pass it to Activity B, but the view shouldn't be active while it's not running, thus will be null.
Create it as static and pass the rootView to it on OnCreate, or pass it to the Application class so it persist between entire application. Verify if its null before doing operations.
I never tryed it, but my guess is that while activity is not finished the rootView can be accesed (its status stays on pause while another activity is active).
Look like you are trying to trigger an action across activities when your preference changed. I suggest to use LocalBroadcastManager to send the message from ActivityB to ActivityA. I assume that your ActivityB is the preference and active activity, and ActivityA is in the back stack:
ActivityB.java
mListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
// create your broadcast intent and pass the value of changed preference
Intent intent = ...
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
};
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(mListener);
ActivityA.java
mBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// handle your change to ActivityA here
}
};
// create intent filter for your preference change broadcast
IntentFilter intentFilter = ...
LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver, intentFilter);
Given that your ActivityA is not yet destroyed, it will be able to catch the broadcast and you can achieve what you want.
I have an activity such that when the user onPause() on that activity, i start a pending intent that modifies some variable such as mSomeIntegerThatNeedsToBeReset after some time (using Alarm Manager and pending intents).
I tried to make this variable static, which works, but i don't want to make things static if i can help it, and i need to reset that value (in activity) from somewhere else.
public class SomeActivity extends Activity {
private Integer mSomeIntegerThatNeedsToBeReset;
}
what's the standard way to access this variable?
Sounds like you either need to bind your service to your activity OR
You could dispatch an Intent from your service to your Activity and clear the state variable.
I have written an activity A, when users press a button, it will do MyConfig.doSomething() where MyConfig is simple class with activity A passed to it.
public class A extends PreferenceActivity {
private MyConfig mMyConfig;
/* pseudo code, when button clicked, call */
mMyConfig.doSomething();
}
In mMyConfig, it accesses SharedPreferences for some configuration. Thus, I can do this to pass the activity to mMyConfig for calling getSharedPreferences().
mMyConfig = new MyConfig ( this );
Here comes my request:
I want to do something that MyConfig.doSomething() already does, but except when users click some button to invoke it, I want to invoke it when Android Boots-Up.
I can write another class to extend BroadcastReceiver and then starts activity A by calling startActivity(A.class), and then in A, do some tricks to make mMyConfig.doSomething() happen. It works but the Application will be shown on screen when Android Boots-Up.
I want to make mMyConfig.doSomething() happen implicitly without letting users be aware of it. I suppose two possible solutions but I don't know how to do it.
Solution A:
Write a class that extends BroadcastReceiver, start a service (instead of activity A) that reads the SharedPreferences of A and create MyConfig object to do doSomething(). However, I don't if this can work if activity itself is never launched and how could I do this (read SharedPreferences from a service)?
Solution B:
Write a class that extends BroadcastReceiver, start activity A without showing it, put it to activity stack by calling startActivity(A.class) in onReceive. Is this possible?
Instead of Activity, which are meant to be visible to the user, you can make your BoardcastReceiver to start a Service instead. It is meant to perform tasks in the background without disturbing the user. The official guide is a nice place to start with.
Edited:
To access the SharedPreference of your application, simply call this line inside your service:
SharedPreferences pref = PreferenceManager.getSharedPreferences();
I have a set of commands that I want my app to run when it's restarted, regardless of what activity it's on. I know I need to put an onRestart() into every one.
Since it's the same set of commands regardless of what activity it's on, is there a way I could have them all refer to a single function for that? It seems like that would be better then having to copy paste the commands into each onRestart() handler. It will be a lot less work if I need to change the set of commands too.
You have a couple of options, depending on the code.
You can put it in a helper class as a static function: public static void doWork() { .. } This should work, unless whatever you are doing depends on being in the activity. You can generally just pass it what it needs though, like the Context.
Or, you could extend Activity with your own class, MyActivity and place the work in that onResume. Then extend MyActivity for each of your real activities. They will now automatically do that work when you call super.onResume(). This works well as long as you really want to do the same thing in every activity, and don't use a lot of specialized activities like ListActivity.
Edit:
public class MyHelper {
public static void doWork() {
// do your work here
}
}
public class MyActivity extends Activity {
public void onResume() {
super.onResume();
MyHelper.doWork();
}
}
A search for "static method" will provide more details.
Derive all your activities from a single class (something like ActivityBase) that, in turn derives from system-provided Activity. Then implement onRestart() in ActivityBase.
Is it your application that is restarting from scratch? Or just your activities that are restarting/resuming?
The Application class has an onCreate() method, and you can extend Application in your app to override its behavior. Just remember to change the name of the application in AndroidManifest.xml so it picks up your custom Application class when starting. This code would run before any activities start up. But it won't run every time an activity is stopped and restarted. If that's what you need, this won't do it.
You could also implement a singleton class that contains an initialize() method, or restart() method. You simply call it from onRestart() in each activity you want it in. It sounds like this special code ought to be localized away from your activities so I don't think I'd recommend extending Activity to put the code there.