how to access Activity's instance variable from Service - android

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.

Related

Keep reference of an activity in the companion object

I have 2 activities: MainActivity and MySecondActivity.
I start MySecondActivity, but while I'm working in it, I receive a callback from an external library in MainActivity. This callback should update some information in MySecondActivity.
Question: Can I keep a reference of MySecondActivity in MainActivity in order to update it later ?
Basically it would be like this:
val mySecondIntent = Intent(applicationContext, MySecondActivity::class.java)
startActivity(mySecondIntent)
(...)
fun MyCallBackFunction(newInfo: Integer)
mySecondIntent.updateMyInfo(newInfo) <-- here I cannot access "MySecondIntent"
I tried to store the reference of mySecondIntent in the companion object but I could not make it work.
Do you have any suggestion ?
Thank you !
Here is my suggestion. Don't let any activity keeps the other activity reference, it's not the best practice.
Suggestion
If the callback you receive has impact on multiple activities, then make it global. I usually create a singleton manager class for handling each global event's logic that may have impact on many places in the app. Anywhere in your app need to listen for the event, register the event to the manager.
For example, my AppLocationManager is a singleton class, responsible for making gps refresh and other location stuff. When location change, fire events to all registered listeners. In your case, both MainActivity and SecondActivity knows the changes and update itself, remember to unregister the listener in activity onDestroy, or you will have a memory leak.
Workaround for quick implementation
If you still want to keep the activity reference for quick modification, which is not recommended, use WeakReference
Store a WeakReference of MySecondActivity as a static global variable:
public static WeakReference<Activity> mTmpAtivity
Unlike default StrongReference, this variable will release the instance if the activity is GC so it's memory safe.

Get root view of one activity from another activity

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.

how to manage button views from BroadcastReceiver

In MainActivity I have few buttons like start,stop and runInBackground..
I am using a service to send location updates..If the phone is restarted then my app will start automatically,I've achieved this by broadcastreceiver.
Now,I need to disable the start button of my app after restarting phone as because service is already started.
Leave the part of checking whether service is running or not,I am checking that using fileInputStream..That is another task..
But,How do I manage the Views which belongs to MainActivity class from a receiver class.
I've tried few things like this::
In MainActivity.java
public static void disable()
{
btnShowLocation.setEnabled(false);
btnStopLocation.setEnabled(true);
runbackground.setEnabled(true);
}
MyReceiver.class
public class MyReceiver extends BroadcastReceiver
{
MainActivity.disable()
}
it was not working..tried another like this:
MainActivity.btnShowLocation.setEnabled(false);
MainActivity.btnStopLocation.setEnabled(true);
MainActivity.runbackground.setEnabled(true);
even this crashing my app..
Now how do I manage button views from BroadcastReceiver..
You could:
Save the state in SharedPreferences (or similar) and query it on Activity's onCreate.
Fire an explicit intent from your receiver to start the Activity and put some extra data into that intent to tell the Activity to disable the button.
Somehow register your Activity with an Application class or a singleton and then call methods on it.

Need Suggestion to do a task when Android Boots-Up

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();

How to get any identifier of the topmost activity?

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
}

Categories

Resources