7

I have a main activity (let's call it A) and a second activity (let's call it B) which's used to change the language of the app. The point is, when I click the button to change the language I also call recreate(); and B changes it language. Until here it's ok. The problem comes when I go back to the main activity (A) and it hasn't updated the language because it hasn't been recreated, so, is there any way to recreate A from B in order to update A?

I use this code to translate the app (eng version example):

public void btnIngles_onClick(View v)
{
    Locale locale = new Locale("en");
    Locale.setDefault(locale);

    Configuration config = new Configuration();
    config.locale = locale;
    this.getApplicationContext().getResources().updateConfiguration(config, null);
    recreate();
}
Drumnbass
  • 867
  • 1
  • 14
  • 35

3 Answers3

7

1) Activity B changes some global settings, accessible via SharedPreferences for example

2) In Activity A do:

@Override
protected void onResume() {
    super.onResume();
    if(didLanguageChange)
      recreate();
}

Problem solved. Activity A will call onResume() since it has switched into a paused state when Activity B came into the foreground.

Droidman
  • 11,485
  • 17
  • 93
  • 141
  • I did it and it calls `recreate()` method but the activity language does not change.. :( `protected void onResume() { super.onResume(); if (idioma.compareTo(Locale.getDefault().getLanguage()) != 0) this.recreate(); }` I've checked that the condition returns true and language is changed, but as I said, A doesn't change its language. – Drumnbass Mar 17 '15 at 18:31
  • @Drumnbass how do you set your texts? Do you use localized strings? – Droidman Mar 17 '15 at 18:41
  • Yes, in fact, the whole app gets translated (even contextual menus on A). The only which doesn't not get updated is A even recreating it, I don't know what to say, it's kinda wierd, but it's also funny xD – Drumnbass Mar 17 '15 at 18:50
  • @Drumnbass Android uses the system locale/language to determine which localized strings to get. How do you change the language? Do you manually change the locale? – Droidman Mar 17 '15 at 19:03
  • Yes I do, I've edited my post to show you the code which I use to change the language. Maybe I do something wrong, but the app gets translated anyway and I think it has not relation with the problem. But you are the master here, let's see what you think! – Drumnbass Mar 17 '15 at 19:08
  • @Drumnbass this is not recommended but anyway, do you check that the locale *actually* gets changed *after* the Activity A is recreated? – Droidman Mar 17 '15 at 19:12
  • I didn't (watching its value at least), but if at this point I go again to B, it's translated – Drumnbass Mar 17 '15 at 19:18
  • @Drumnbass add a locale check to Activity's A `onCreate()` and change it again if needed. You will need some other class to provide the current locale selected by user. Explicitly changing the locale is a kind of "fighting the system" so get yourself ready for multiple checks – Droidman Mar 17 '15 at 19:27
  • Omg, I'm so sorry for the wasted time. I've actually found the problem. I forgot that I tried to override the `recreate()` method on Activity A (trying to call it from B) and finally I left it empty... after remove that "fail override" it works great! I really appreciate your help. Thanks!! :) – Drumnbass Mar 17 '15 at 19:40
4

You need to implement onActivityResult() in your Activity. This link has more information and should be very helpful to you. In a nutshell:

Inside your Activity A, you'll need to create a variable used as a request code, something like this:

private static final int ACTIVITY_B_REQUEST = 0;

And then, in your button's onClick listener, you'll start the activity using an intent and the startActivityForResult() function:

Intent myIntent = new Intent(ActivityA.this, ActivityB.class);
startActivityForResult(myIntent, ACTIVITY_B_REQUEST);

This will start Activity B for you. Whenever Activity B finishes, onActivityResult will be called. You can override it and implement it in whichever way you need, but it may look something like this:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode == ACTIVITY_B_REQUEST && resultCode == RESULT_OKAY){
        // Handle this by doing what you need to refresh activity A.
    } else{
        super(requestCode, resultCode, data);
    }   
}
AdamMc331
  • 16,492
  • 10
  • 71
  • 133
  • IMHO, isn't it a bit of an overkill to start an `Activity` for result just to check whether it has changed some setting? – Droidman Mar 17 '15 at 18:10
  • @Droidman You're right, it may be overkill. Unless they need information back from the new activity, such as which language it needed to be changed to? This just seemed like the proper approach to me because they wanted to use ActivityA to handle whatever happens when ActivityB finishes. – AdamMc331 Mar 17 '15 at 18:14
  • well, I'm getting your point though I would rather add some kind of check to the `OnResume()`. Maybe this is just my personal approach since I always implement helper classes which monitor changes of important settings and notify all subscribers that are interested in those changes ;) – Droidman Mar 17 '15 at 18:22
  • @Droidman definitely. I am still learning, just trying to get some experience putting some Android answers out there. They teach me something new, too! Do you think this answer should be removed? – AdamMc331 Mar 17 '15 at 18:23
  • 3
    of course not, since your example offers a clean and working answer to the question. It's a really rare case where only one correct answer can exist. I'm not considering your answer "wrong" in any way, just shared my personal opinion – Droidman Mar 17 '15 at 18:25
  • @Droidman definitely appreciate it, I agree 100%. Just making sure that this wasn't *wrong*. – AdamMc331 Mar 17 '15 at 18:29
2

Restart your app:

startActivity(new Intent(this, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent
                .FLAG_ACTIVITY_CLEAR_TOP));
greywolf82
  • 21,813
  • 18
  • 54
  • 108