I am developing android app in which I have 2 activities. I want to close activity A from activity B on button press and recreate activity A. How to do it need help?
You can use sendBroadcast method, by this way you can close one or more activities.
In your ActivityB use this code:
public class ActivityA extends AppCompatActivity {
public static final String FINISH_ALERT = "finish_alert";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.registerReceiver(this.finishAlert, new IntentFilter(FINISH_ALERT));
}
BroadcastReceiver finishAlert = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
ActivityA.this.finish();
}
};
#Override
public void onDestroy() {
super.onDestroy();
this.unregisterReceiver(finishAlert);
}
}
and in your ActivityB call this command to finish it:
Intent i = new Intent(ActivityA.FINISH_ALERT);
this.sendBroadcast(i);
Related
I want to update an Activity which is not the MainActivity.
So I start a second Activity via a onClick method in MainActivity.
Now the Activty "SecondActivity" is at front.
When I started a Thread in the "MainActivity" how can I reference to the "SecondActivity" to update their TextViews and so on?
PseudoCode
public class activity_MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ThreadSome threadSome= new ThreadSome();
threadSome.start()
}
onClick(View View){
Intent intent = new Intent(this, activity_Second.class);
startActivity(intent);
}
}
Inside Thread
public class ThreadSome extends Thread {
#Override
public void run() {
//This is what I don't know, so I just write what I want to do.
// I know the following Code is wrong and not working.
activity_Second.someTextView.setText("Hi");
}
}
Is a WeakReference the best way to do this, or better work with static TextView objects? How would you solve this problem?
Based on your description, I think you want to do something where there will be some ui change in activity stack based on some event performed in the forground activity. There is a good way to use onActivityResult() via startActivityForResult() but if this is not fullfilling your requirement directly then you can try something like below:
/**
UpdateActivity is the activity where some ui update or action will be taken based on event in EventActivity.
**/
public class UpdateActivity extends Activity {
private BroadcastReceiver mReceiver;
public static final String ACTION_UPDATE = "com.my.internal.activity.action";
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update);
......
//Prepared Intent for broadcast receiver
IntentFilter intentFilter = new IntentFilter(ACTION_UPDATE);
//registering our receiver
this.registerReceiver(mReceiver, intentFilter);
.....
}
//This is the receiver section where you need to do the ui update
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//extract our message from intent
String some_msg = intent.getStringExtra("msg_1"); //parameter received if passed in intent when broadcast called.
//log our message value
Log.i("Message", some_msg);
updateActivityUi();
}
};
private void updateActivityUi() {
// you need to write the code for the update which you want to do after an event done in other activity.
}
#Override
protected void onDestroy() {
super.onDestroy();
//unregister our receiver
this.unregisterReceiver(this.mReceiver);
}
}
public class EventActivity extends Activity {
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event);
......
//Sending BroadcastReceiver against the action ACTION_UPDATE and it will be received by UpdateActivity.
if(condition_for_event) {
Intent i = new Intent(UpdateActivity.ACTION_UPDATE).putExtra("msg_1", "Hey! an event performed here.");
this.sendBroadcast(i);
}
.....
}
....
}
Let me know if it solved your issue.
Store Activity:
public void unlockcup2(){
}
Main Activity:
public void unlock2(){
x = (x-100);
ImageView img5 = (ImageView) findViewById(R.id.bluecake);
img5.setVisibility(View.VISIBLE);
}
Soo, I want to make it so when my button in Store activity(Witch calls unlockcup2()) Call unlock2 in my MainActivity . How do I do this?
localbroadcastmanager can do this job. Send a broadcast in the StoreActivity and receive it in the MainActivity and call unlock2()
MainActivity (Receiver)
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// in this case, there's only one type of action, so no need to check action
unlock2();
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
...
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver,
new IntentFilter("custom-action-name"));
}
#Override
protected void onDestroy() {
...
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
}
StoreActivity (Sender)
public void unlockcup2() {
...
LocalBroadcastManager.getInstance(this)
.sendBroadcast(new Intent("custom-action-name"));
}
I have a couple of activities that extends from a custom class I wrote which in turn extends from Activity. I've named this class LoginFinisherActivity and on overriden its onCreate function like this
private BroadcastReceiver finishReceiver = null;
public static final String ACTION_FINISH_LOGIN = "ACTION_FINISH_LOGIN";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("LoginFinisherActivity", "onCreate() called.");
finishReceiver = new FinishReceiver();
registerReceiver(finishReceiver, new IntentFilter(ACTION_FINISH_LOGIN));
}
Now the activities that extended LoginFinisherActivity are the ones that need to retain their states whenever I click the system's back button. i.e. I'm at a welcome activity and I want to go to and forth to a sign up/sign in activities. But when I either sign in or sign up, I land on NavigationActivity which extends Activity, i.e. it needs to be closed down not gone back to whichever activity it came from.
I was able to do that if I removed the onPause and onResume functions from the LoginFinisherActivity.
My FinishReceiver's code is as follows:
private final class FinishReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_FINISH_LOGIN)) {
finish();
}
}
}
Thank you for your help in advance.
Edit: following are the overriden onPause and onResume functions in the LoginFinisherActivity
#Override
protected void onPause() {
Log.d("LoginFinisherActivity", "onPaused() called.");
super.onPause();
if(finishReceiver != null) {
unregisterReceiver(finishReceiver);
finishReceiver = null;
}
}
#Override
protected void onResume(Context context, Intent intent) {
Log.d("LoginFinisherActivity", "onResume() called.");
super.onResume();
if (intent.getAction().equals(ACTION_FINISH_LOGIN)) {
finish();
}
else {
if(finishReceiver == null)
registerReceiver(finishReceiver, new IntentFilter(ACTION_FINISH_LOGIN));
}
}
Assuming you want to finish your activities on successful login/register, I think the best approach would be using startActivityForResult(Intent intent, int REQUEST_CODE) instead of handling more intents that make the flow more complex.
You can also make use of android.support.v4.content.IntentCompatIntentCompat.makeRestartActivityTask(...) if you want to terminate the previous stack of activities.
Hope it helps.
In my app, whenever I receive a push notification, I will perform a check if my mainActivity is visible to the user to do something...
I have a static boolean value that is set true inside onResume of mainActivity, and false inside it's onPause.
What should I do inside the onMessage
#Override
protected void onMessage(Context context, Intent intent)
{
if(mainActivity == visible)
//do something inside mainactivity.. change text inside edittext
else
//do something else
}
any insights ?
I'm not a fan of keeping static references to activities. I think they're a can of worms ready to explode on you. So you'll suggest an alternative to #TeRRo answer:
on your global BroadcastReceiver onMessage you'll send a LocalBroadcast that your activity will be listening to. Like this:
private static final String ACTION_PUSH_RECEIVED = "com.myapp.mypackage.action.pushReceived";
public static final IntentFilter BROADCAST_INTENT_FILTER = new IntentFilter(ACTION_PUSH_RECEIVED);
#Override
protected void onMessage(Context context, Intent intent) {
Intent i = new Intent(ACTION_PUSH_RECEIVED);
i.putExtra( ... add any extra data you want... )
LocalBroadcastManager.getInstance(context).sendBroadcast(i);
}
and now we make the activity listen to it:
#Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(context)
.registerReceiver(mBroadcastReceiver, BroadcastReceiverClass.BROADCAST_INTENT_FILTER);
}
#Override
protected void onPause() {
LocalBroadcastManager.getInstance(context)
.unregisterReceiver(mBroadcastReceiver);
super.onPause();
}
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent){
// read any data you might need from intent and do your action here
}
}
To avoid this, you should manage activities references. Add the name of the application in the manifest file:
<application
android:name=".MyApp"
....
</application>
Your application class :
public class MyApp extends Application {
public void onCreate() {
super.onCreate();
}
private Activity mCurrentActivity = null;
public Activity getCurrentActivity(){
return mCurrentActivity;
}
public void setCurrentActivity(Activity mCurrentActivity){
this.mCurrentActivity = mCurrentActivity;
}
}
Create a new Activity :
public class MyBaseActivity extends Activity {
protected MyApp mMyApp;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mMyApp = (MyApp)this.getApplicationContext();
}
protected void onResume() {
super.onResume();
mMyApp.setCurrentActivity(this);
}
protected void onPause() {
clearReferences();
super.onPause();
}
protected void onDestroy() {
clearReferences();
super.onDestroy();
}
private void clearReferences(){
Activity currActivity = mMyApp.getCurrentActivity();
if (currActivity != null && currActivity.equals(this))
mMyApp.setCurrentActivity(null);
}
}
So, now instead of extending Activity class for your activities, just extend MyBaseActivity. Now, you can get your current activity from application or Activity context like that :
Activity currentActivity = ((MyApp)context.getApplicationContext()).getCurrentActivity();
Or why don't you use the Local broadcasts when you receive the push notification, and receive it in your activity, and do respective changes or actions.
And if they are UI intensive tasks, bind your activity to a service, and receive the push notification and perform the action in this service and use the result in the activity.
Consider i am using five screen pages for project "A".Each page is having switching between other pages sequentially one by one,my need is to do close all the page when i am clicking the button "exit" from the page five which is the last one.
I have used this below code,but the problem is only the last page is getting close others are not.
find my code below
Button extbtn = (Button)findViewById(R.id.but_Exit);
extbtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent();
setResult(RESULT_OK, intent);
finish();
} });
Thanks for your time!
Make all five activities extend a BaseActivity that registers a BroadcastReceiver at onCreate (and unregisters at onDestroy).
When extbtn is clicked, send a broadcast to all those BaseActivities to close themselves
for example, in your BaseActivity add:
public static final String ACTION_KILL_COMMAND = "ACTION_KILL_COMMAND";
public static final String ACTION_KILL_DATATYPE = "content://ACTION_KILL_DATATYPE";
private KillReceiver mKillReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
...
...
mKillReceiver = new KillReceiver();
registerReceiver(mKillReceiver, IntentFilter.create(ACTION_KILL_COMMAND, ACTION_KILL_DATATYPE));
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mKillReceiver);
}
private final class KillReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
finish();
}
}
and at extbtn's onClick call:
extbtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// send a broadcast that will finish activities at the bottom of the stack
Intent killIntent = new Intent(BaseActivity.ACTION_KILL_COMMAND);
killIntent.setType(BaseActivity.ACTION_KILL_DATATYPE);
sendBroadcast(killIntent);
Intent intent = new Intent();
setResult(RESULT_OK, intent);
finish();
}
});