3

Here is the code of my onActivityResult method:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == Activity.RESULT_OK) {
        String contents = data.getStringExtra("SCAN_RESULT");
        if (contents.length() == 26) {
            BillBarcode barcode = new BillBarcode(contents);
            edtBillId.setText(barcode.extract(BillBarcode.BarcodePart.BillId));
            edtPaymentId.setText(barcode.extract(BillBarcode.BarcodePart.PaymentId));
            launchService();
        } else {
            Dialog dialog = new DialogBuilder()
                    .setTitle(getString(R.string.dialog_title_global_error))
                    .setMessage(getString(R.string.unknown_barcode))
                    .build(getActivity());

            dialog.show();
        }
    }
}

The problem is that getString(R.string.dialog_title_global_error) and getString(R.string.unknown_barcode) always returns english value while I have Farsi value too and the locale is farsi too.

The problem only exist in this method.

Farsi value:

<string name="unknown_barcode">بارکد قابل استفاده نیست.</string>

English value:

<string name="unknown_barcode">Unknown barcode</string>

EDIT

I have a setting page and set my locale when user selects persian from language page by this code:

      String languageToLoad = "fa";
Resources res = context.getResources();
            // Change locale settings in the app.
            android.content.res.Configuration conf = res.getConfiguration();
            conf.locale = new Locale(languageToLoad);
Husein Behboudi Rad
  • 5,434
  • 11
  • 57
  • 115
  • could you post `string.xml` values? – Amy Jul 20 '15 at 11:38
  • Set your farsi local first – M D Jul 20 '15 at 11:39
  • it already is set to farsi – Husein Behboudi Rad Jul 20 '15 at 11:40
  • I post the string items. Any item in this methods returns english value while in other parts I can get farsi values – Husein Behboudi Rad Jul 20 '15 at 11:42
  • Where is your string.xml in persian located? Are you modifying the system `Locale` programmatically in your code? – m0skit0 Jul 20 '15 at 11:44
  • the persian string.xml is located in values folder and english strings are located in values-en. every thing works right in every place other than this method – Husein Behboudi Rad Jul 20 '15 at 11:48
  • can it because of showing the barcodescanner activity ?? – Husein Behboudi Rad Jul 20 '15 at 11:49
  • Maybe the reference to the string resource is wrong - try doing a clean build. – Theo Lassonder Jul 20 '15 at 11:51
  • I don't think so. Does the dialog title show in persian or also in English? Uninstall, clean, and install it, maybe the data folder is messed up. – m0skit0 Jul 20 '15 at 11:51
  • Can you double check the locale when the method is called (use `getResources().getConfiguration().locale`)? Because's there's https://stackoverflow.com/questions/4964829/why-might-resources-getstring-intermittently-return-strings-from-the-wrong-loc, which makes me guess `onActivityResult()` might be called with a different context. – dhke Jul 20 '15 at 11:52
  • @dhke I think the `Context` is the same for the whole app ([`Application`](http://developer.android.com/reference/android/app/Application.html) class), not a different one for each `Activity`. – m0skit0 Jul 20 '15 at 11:53
  • 2
    @dhke, the locale in methods before calling child activity is fa but in the onActivityResult() is "en-US" !! Should I set it to fa again ?? – Husein Behboudi Rad Jul 20 '15 at 11:54
  • @m0skit0: There's more than one of them, sometime it's actually important to use `Context.getApplicationContext()` because that lives as long as the app, while the activity context dies with the activity. – dhke Jul 20 '15 at 11:55
  • Context.getApplicationContext() have compile error. says error – Husein Behboudi Rad Jul 20 '15 at 12:00
  • 1
    @HuseinBehbudiRad: Are you setting the locale manually inside the app? If so, remember that between `startActivityForResult()` and `onActivityResult()` your activity may get destroyed. That maybe the problem, but I'm not yet sure if there isn't some other bug in hiding. Also: My comment about `getApplicationContext()` is not related to this question, only to @m0skit0's comment. – dhke Jul 20 '15 at 12:01
  • @HuseinBehbudiRad I asked before: are you modifying the Locale programmatically in your code? If so please post the code. – m0skit0 Jul 20 '15 at 12:06
  • Finally. Why are you using a language setting in your app? It's a poor design choice. That's just confusing to user and prone to errors. I suggest you remove this and let user choose language in phone settings. – m0skit0 Jul 20 '15 at 12:07
  • It is because in my area it is common that users use english as device language but prefer to have applications with persian language – Husein Behboudi Rad Jul 20 '15 at 12:10
  • so what is the best way to fix it? – Husein Behboudi Rad Jul 20 '15 at 12:18
  • But most apps do not allow that... Anyways, there's no good way to fix it. You can set the `Locale` to persian again in `onActivityResult()`. – m0skit0 Jul 20 '15 at 12:51
  • check this sample, this problem looks pretty similar. https://stackoverflow.com/a/46055716/4845324 – Saeed Sep 05 '17 at 13:12

1 Answers1

1

Let me try to round up all the comments in an answer. Your problem is a combination of two implementation mistakes:

  1. You are setting the locale of the current Activitys context programmatically. However you are doing so in an unsupported way that may yield incorrect results.

  2. When your activity gets a result from another activity in OnActivityResult(), your Activity either gets restarted completely or the context configuration gets reset to the system's default locale. Either way, the locale you set up in the settings dialog is lost.

Solutions

  1. The proper way of changing the App's locale locally is outlined here: Changing Locale within the app itself.

In particular, while just changing the locale in the configuration class may work for you, it is clearly not the correct way to change an application's locale. Doing it properly requires a little more work:

  Locale locale; // set to locale of your choice, i.e. "fa"
  Configuration config = getResources().getConfiguration();
  config.setLocale(locale); // There's a setter, don't set it directly     
  getApplicationContext().getResources().updateConfiguration(
      config,
      getApplicationContext().getResources().getDisplayMetrics()
  );
  // you might even need to use getApplicationContext().getBaseContext(), here.
  Locale.setLocale(locale);

Setting the locale on the application context should survive the restart of an activity, but as per Android's lifecycle guarantees, you should not assume that the locale stays around.

  1. If you really need the ability to locally change the locale of your app, you should save the user specified locale (e.g. in a SharedPreference) and obtain and re-set it when the app or your activity is restarted (i.e. at least in OnCreate()). Remember that Android is free to save and restart your activities at any time outside of your control and it is your responsibility to handle the restart gracefully.
dhke
  • 15,008
  • 2
  • 39
  • 56