I have an android application in which I use two themes. On theme change I need to recreate all the activities and Fragments inside that to be recreated.
The same way our application get recreated using saved instnce state.
Is there any way I can force my Activity to call the saved instance state ? IF it is possible how I can do that ? If not why ? Is there any alternative to Achieve this ?
My current code looks like below.
public static final void restartActivity(final FragmentActivity activity){
activity.finish();
activity.startActivity(new Intent(activity, activity.getClass()));
}
The issue with this is the fragment back stack is not getting recreated. Any help would be greatly appreciated.
Your state is not saved because you're creating a new instance of Activity. As a solution, you can pass your state to this new instance as Intent extras and restore state in onCreate from those extras.
Related
I have multiple fragments with its activity.
When I refresh in MainActivity, I want all fragment's activity to refresh as well. Because I work with database and it involves refreshing others fragments to update the data.
MainActivity.kt
swipeRefresh.setOnRefreshListener {
// refreshing MainActivity only
// I don't know how to call fragment's activity here
swipeRefresh.isRefreshing = false
}
Fragment is dependent on activity and activity is not dependent on fragment. What you do in activity will affect the fragment. Do use this a starting point to look up.
In the activity, you can call recreate() to "recreate" the activity (API 11+)
or you can use this for refreshing an Activity from within itself.
finish();
startActivity(getIntent());
I am currently developing a Voice Recorder app for Android. I am trying to access a few methods in my MainActivity from my Settings activity, in order to change some settings for my MediaRecorder.
I have the method below, which sets up the Audio Settings for the recording, in my MainActivity.
// set up all audio settings
private void setAudioSettings() {
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mediaRecorder.setAudioSamplingRate(44100);
mediaRecorder.setAudioEncodingBitRate(96000);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.HE_AAC);
}
In my Settings activity, I have a standard preferences screen that I would like to show options to change the audio codec, sampling rate, etc. of the media recorder in MainActivity.
How can I access the setAudioSettings method from MainActivity here in order to do so?
If you need to see more code or screenshots, please let me know.
Make that method as static so you can call without creating the class object
public static void yourMethod(){
//Write your code here
}
And call your method like this way:
MainActivity.yourMethod();
The short answer is you should not use the functions of your one activity into another activity.
For your case, I would suggest you to have a singleton object or shared preference to store your data of settings screen. Then in onStart of MainActivity, read the singleton object or shared preference and call #setAudioSettings method accordingly.
save setting i.e values in shared preferences and then get from preferences in Main Activity.
You can make your method static by:
public static void setAudioSettings() {
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mediaRecorder.setAudioSamplingRate(44100);
mediaRecorder.setAudioEncodingBitRate(96000);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.HE_AAC);
}
But to do that mediaRecorder needs to be static also.
Later you can call this method from any activity by:
MainActivity.setAudioSettings();
You can learn more about static keyword for example here.
But, I am not sure that use of static method is the best solution for exactly your problem, maybe will be better to set SharedPreferences in your SettingActivity and later in onResume() of your MainActivity call setAudioSettings() method and get there values from SharedPreferences?
I want to access the activity lifecycle method of a different activity from the present one... Can i do that? for example i have 2 activities A and B. I want to access the onStop method of activity A from activity B. can i do that? i'm trying to check the online of a user in my app which has multiple activities so i want to write code which is like = If onStop/onDestroy method of both the activities are called show that the user is offline... The code im using is
#Override
public void onStart(){
super.onStart();
mDatabaseReference.child("Online").setValue(true);
}
#Override
public void onStop(){
super.onStop();
mDatabaseReference.child("Online").setValue(false);
}
Can someone please help me out
Use Application.ActivityLifecycleCallbacks in your Application class. This way you just need to register your activities to the callbacks and from the application class only you can track down wheather any activity is present or not.
For more info please refer to this answer
To set the value You can use SharedPreferences. Declare the instance of sharedpreference at application level.
In Activity A and B you can set the value in onStop(), onDestroy() and onStart() block.
In an App I am currently working on I am facing a problem regarding the communication between Activities.
Basicly I have a UI-Component, which is similar to a Combobox. However, the list of the possible values for this component has to be openend in a new Activity.
So when you clicked the component, a new Activity is opened, using startActivityForResult.
When you select the new value, it is put inside a Bundle and returned to the previous Activity. I then need to use the onActivityResult-method to get the selected value and set it to the component.
That means, that every Activity that uses this component needs to override onActivityResult and refresh the component with the new value.
What I want instead is, that the component takes care about all this stuff and you only have to register a Listener, just like you do it for a TextView and similar components.
But at the moment I just can't find a good way to do that, as the communication is tightly bound to the Activity and I just can't get the result of the Activity outside the onActivityResult.
Does anyone know a good solution for this problem?
Solution to this- use EventBus and post sticky event on it. By doing so you don't have to override onActivityResult.
The workflow will be as following:
- Create event object with your data
- Remove all sticky events of the same type from the Bus
- post new values by .sendSticky() method.
That event will be around until something remove it from the bus
- start another activity
- in this activity override method, subscribing to that event type, in it:
a) take and process event with your argument
b) remove it from the bus
- subscribe to the bus (second Activity) in onResume() method
- unsubscribe from the bus in .onPause() method
The point is, that this allow you to seamlessly handle lifecycle of second Activity, and you can subscribe/unsubscribe to the bus in base class
What about using BroadCastReceiver?
Basically you send a broadcast and every activity that is registered to receive that broadcast will receive that broadcast will receive the message in onReceive
First of all declare in the manifesto what you are going to listen for, something like:
<receiver android:name=".TestBroadCast”>
<intent-filter>
<action android:name="io.test.TEST"/>
</intent-filter>
</receiver>
Than simply extend BroadCastReceiver
public class TestBroadCastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//TODO: Handle the Intent received.
}
Example of how to send a broadcast:
public static final String INTENT_ACTION = "io.test.TEST";
public static final String INTENT_EXTRA = "someData";
Intent intent = new Intent();
intent.setAction(INTENT_ACTION);
intent.putExtra(INTENT_EXTRA,"test");
sendBroadcast(intent);
And you will get the Intent and than you can handle it as you wish :)!
UPDATE ~ Registering from code instead of manifesto
To avoid registering the service from the Manifesto you can do it from the code, with a code similar to the following listing:
IntentFilter intentFilter = new IntentFilter("io.test.TEST");
TestBroadCastReceiver mReceiver = new TestBroadCastReceiver();
context.registerReceiver(mReceiver, intentFilter);
P.S.
I suggest you using LocalBroadcastReceiver if you don't need other applications to be able to send results insted of the common BroadcastReceiver for security reasons
You can implement Observer Design Pattern, the better implementation of that are BroadcastReceiver and a Library which implement event bus design Otto
Hello #Alex Shutov was right Try this
https://github.com/greenrobot/EventBus
http://greenrobot.org/eventbus/
Use EventBus here is the link https://github.com/greenrobot/EventBus
only 3 steps and yes it is 3rd PartyLibrary. its very light should not affect your app size as well
Generally for such scenario I will keep the data in Main Activity as static data and use and update them in other activities.
For example you can declare and populate these 2 variables in Main Activity (i.e. MainActivity)
public static ArrayList arrayList ;
public static SparseBooleanArray sparseBooleanArray ;
now all other activities while populating list values, they can populate from array list using name MainActivity.arrayList. When user select or unselect a value only sparseBooleanArray will be updated with a boolean value.
while populating values first time in arrayList and sparseBooleanArray , ensure to use same index so they will be in sync
arrayList.add(1,"List Item 1") ;
sparseBooleanArray.put(1,false ) ; // represent selected value for List Item 1
In case you have plan to use this functionality for multiple activities, arraylist will remain same, however there will be one SparseBooleanArray for each activity to store activity wise selected values.
I have created a class that is extending from CountDownTimer, It has a a method onFinish() which calls when timer expires.
There are 6 Activities, user can be in any activity when timer expires, So in CounterTimerwhen Finish() method calls , i need to show an Alert Message to the user,along with i need to redirect user to Login page.
Things getting confusing, as i cannot call Intent class in the Normal Class, I can also not pass the context, as user can be in any activity.
I have written following code, but its not helping out.
I am using context here, but its giving error message on passing context to Intent
public class CounterClass extends CountDownTimer implements ITMServiceEvent {
#Override
public void onFinish() {
if(sql_code.equalsIgnoreCase("0")) {
String resultCode = command1.getString("result");
context.startActivity(context.getApplicationContext(), MainActivity.class);
}
Calling Timer at the Start of Wizard, in a Fragment
CounterClass counterClass= new CounterClass(180000,1000);
counterClass.setTextView(tvTimer);
counterClass.start();
There are two parts of your question, first is how you can clean up the Activity stack and start a new Activity on Top of them, I suppose this would be the LoginActivity in your case.
To do this, you need to set the Flag of your LoginActivity Intent when you want to start it,
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
And the second part is, you want to be able to finish the current activity after showing a dialog to the user. I assume your Timer is a Service Class, which runs in the background. The way to tell your current activity that the Time is Up ! is to send a Broadcast Message. Preferably, LocalBroadcastManager can help you out. You can have a BaseActivity class where all of your 6 Activities can be extended from it and you can register/unregister LocalBroadcastManager to/from those activities in the BaseActivity class (register in onResume and unregister in onPause). After you register them you just need to implement and handle the onReceive method where you can show a dialog and start the LoginActivity after finishing the current one.