Merge pull request #10821 from osmandapp/add_app_restart_after_settings_import

Add restart button after settings import if language was changed
This commit is contained in:
Vitaliy 2021-02-15 11:41:07 +02:00 committed by GitHub
commit 5698f7c74e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 249 additions and 123 deletions

View file

@ -66,28 +66,64 @@
<include layout="@layout/divider" />
<FrameLayout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dialog_button_height"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginTop="@dimen/content_padding_small"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginBottom="@dimen/content_padding_small"
android:background="?attr/dlg_btn_secondary">
android:orientation="horizontal" >
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/button_close"
android:layout_width="match_parent"
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:gravity="center"
android:text="@string/shared_string_close"
android:textColor="?attr/active_color_basic"
android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_medium"
tools:text="Button" />
android:background="?attr/dlg_btn_secondary"
android:layout_weight="1">
</FrameLayout>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/button_close"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:gravity="center"
android:text="@string/shared_string_close"
android:textColor="?attr/active_color_basic"
android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_medium" />
</FrameLayout>
<View
android:id="@+id/buttons_divider"
android:layout_width="@dimen/content_padding"
android:layout_height="match_parent"
android:visibility="gone"
tools:visibility="visible" />
<FrameLayout
android:id="@+id/button_restart_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:background="?attr/dlg_btn_secondary"
android:layout_weight="1"
android:visibility="gone"
tools:visibility="visible">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/button_restart"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:gravity="center"
android:text="@string/restart"
android:textColor="?attr/active_color_basic"
android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_medium" />
</FrameLayout>
</LinearLayout>
</LinearLayout>

View file

@ -12,6 +12,7 @@
-->
<string name="restart">Restart</string>
<string name="elevation_data_descr">Routing could avoid strong uphills</string>
<string name="map_orientation_threshold_descr">Don\'t rotate map view if speed is less than a threshold</string>
<string name="snap_to_road_descr">Current location icon will be snapped to the current navigation route</string>

View file

@ -514,7 +514,7 @@ public class AppInitializer implements IProgress {
return null;
}
});
app.regions.setLocale(app.getLanguage(), app.getCountry());
app.regions.setLocale(app.getLanguage(), app.getLocaleHelper().getCountry());
}

View file

@ -237,7 +237,7 @@ public class CustomOsmandPlugin extends OsmandPlugin {
final SettingsHelper.SettingsImportListener importListener = new SettingsHelper.SettingsImportListener() {
@Override
public void onSettingsImportFinished(boolean succeed, @NonNull List<SettingsItem> items) {
public void onSettingsImportFinished(boolean succeed, boolean needRestart, @NonNull List<SettingsItem> items) {
if (AndroidUtils.isActivityNotDestroyed(activity)) {
progress.dismiss();
}

View file

@ -59,6 +59,7 @@ import net.osmand.plus.download.DownloadService;
import net.osmand.plus.download.IndexItem;
import net.osmand.plus.helpers.AvoidSpecificRoads;
import net.osmand.plus.helpers.DayNightHelper;
import net.osmand.plus.helpers.LocaleHelper;
import net.osmand.plus.helpers.LocationServiceHelper;
import net.osmand.plus.helpers.LockHelper;
import net.osmand.plus.helpers.WaypointHelper;
@ -126,6 +127,7 @@ public class OsmandApplication extends MultiDexApplication {
private final SQLiteAPI sqliteAPI = new SQLiteAPIImpl(this);
private final OsmAndTaskManager taskManager = new OsmAndTaskManager(this);
private final UiUtilities iconsCache = new UiUtilities(this);
private final LocaleHelper localeHelper = new LocaleHelper(this);
// start variables
ResourceManager resourceManager;
@ -166,10 +168,7 @@ public class OsmandApplication extends MultiDexApplication {
MeasurementEditingContext measurementEditingContext;
OnlineRoutingHelper onlineRoutingHelper;
private Resources localizedResources;
private Map<String, Builder> customRoutingConfigs = new ConcurrentHashMap<>();
private Locale preferredLocale;
private Locale defaultLocale;
private File externalStorageDirectory;
private boolean externalStorageDirectoryReadOnly;
@ -218,7 +217,7 @@ public class OsmandApplication extends MultiDexApplication {
removeSqliteDbTravelFiles();
}
checkPreferredLocale();
localeHelper.checkPreferredLocale();
appInitializer.onCreateApplication();
// if(!osmandSettings.FOLLOW_THE_ROUTE.get()) {
// targetPointsHelper.clearPointToNavigate(false);
@ -402,6 +401,10 @@ public class OsmandApplication extends MultiDexApplication {
return oprAuthHelper;
}
public LocaleHelper getLocaleHelper() {
return localeHelper;
}
public synchronized DownloadIndexesThread getDownloadThread() {
if (downloadIndexesThread == null) {
downloadIndexesThread = new DownloadIndexesThread(this);
@ -416,7 +419,8 @@ public class OsmandApplication extends MultiDexApplication {
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
public void onConfigurationChanged(@NonNull Configuration newConfig) {
Locale preferredLocale = localeHelper.getPreferredLocale();
if (preferredLocale != null && !newConfig.locale.getLanguage().equals(preferredLocale.getLanguage())) {
super.onConfigurationChanged(newConfig);
// ugly fix ! On devices after 4.0 screen is blinking when you rotate device!
@ -430,53 +434,10 @@ public class OsmandApplication extends MultiDexApplication {
}
}
public void checkPreferredLocale() {
Configuration config = getBaseContext().getResources().getConfiguration();
String pl = osmandSettings.PREFERRED_LOCALE.get();
String[] split = pl.split("_");
String lang = split[0];
String country = (split.length > 1) ? split[1] : "";
if (defaultLocale == null) {
defaultLocale = Locale.getDefault();
}
if (!Algorithms.isEmpty(lang)) {
if (!Algorithms.isEmpty(country)) {
preferredLocale = new Locale(lang, country);
} else {
preferredLocale = new Locale(lang);
}
}
Locale selectedLocale = null;
if (!Algorithms.isEmpty(lang) && !config.locale.equals(preferredLocale)) {
selectedLocale = preferredLocale;
} else if (Algorithms.isEmpty(lang) && defaultLocale != null && Locale.getDefault() != defaultLocale) {
selectedLocale = defaultLocale;
preferredLocale = null;
}
if (selectedLocale != null) {
Locale.setDefault(selectedLocale);
config.locale = selectedLocale;
config.setLayoutDirection(selectedLocale);
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
if (android.os.Build.VERSION.SDK_INT >= 17) {
Configuration conf = new Configuration(config);
conf.locale = selectedLocale;
localizedResources = createConfigurationContext(conf).getResources();
}
}
}
public static final int PROGRESS_DIALOG = 5;
public void checkApplicationIsBeingInitialized(Activity activity, AppInitializeListener listener) {
// start application if it was previously closed
startApplication();
if(listener != null) {
if (listener != null) {
appInitializer.addListener(listener);
}
}
@ -717,7 +678,6 @@ public class OsmandApplication extends MultiDexApplication {
}
}
public TargetPointsHelper getTargetPointsHelper() {
return targetPointsHelper;
}
@ -823,7 +783,7 @@ public class OsmandApplication extends MultiDexApplication {
themeResId = R.style.OsmandLightTheme;
}
}
setLanguage(c);
localeHelper.setLanguage(c);
c.setTheme(themeResId);
}
@ -850,53 +810,18 @@ public class OsmandApplication extends MultiDexApplication {
return s;
}
public void setLanguage(Context context) {
if (preferredLocale != null) {
Configuration config = context.getResources().getConfiguration();
String lang = preferredLocale.getLanguage();
if (!Algorithms.isEmpty(lang) && !config.locale.getLanguage().equals(lang)) {
preferredLocale = new Locale(lang);
Locale.setDefault(preferredLocale);
config.locale = preferredLocale;
context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
} else if (Algorithms.isEmpty(lang) && defaultLocale != null && Locale.getDefault() != defaultLocale) {
Locale.setDefault(defaultLocale);
config.locale = defaultLocale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
}
}
}
public String getCountry() {
String country;
if (preferredLocale != null) {
country = preferredLocale.getCountry();
} else {
country = Locale.getDefault().getCountry();
}
return country;
}
public String getLanguage() {
String lang;
if (preferredLocale != null) {
lang = preferredLocale.getLanguage();
} else {
lang = Locale.getDefault().getLanguage();
}
if (lang != null && lang.length() > 3) {
lang = lang.substring(0, 2).toLowerCase();
}
return lang;
return localeHelper.getLanguage();
}
@Override
public AssetManager getAssets() {
return localizedResources != null ? localizedResources.getAssets() : super.getAssets();
return getResources() != null ? getResources().getAssets() : super.getAssets();
}
@Override
public Resources getResources() {
Resources localizedResources = localeHelper.getLocalizedResources();
return localizedResources != null ? localizedResources : super.getResources();
}

View file

@ -0,0 +1,118 @@
package net.osmand.plus.helpers;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import net.osmand.StateChangedListener;
import net.osmand.plus.OsmandApplication;
import net.osmand.util.Algorithms;
import java.util.Locale;
public class LocaleHelper {
private final OsmandApplication app;
private Locale defaultLocale;
private Locale preferredLocale;
private Resources localizedResources;
public LocaleHelper(OsmandApplication app) {
this.app = app;
}
public void checkPreferredLocale() {
Configuration config = app.getBaseContext().getResources().getConfiguration();
String pl = app.getSettings().PREFERRED_LOCALE.get();
String[] split = pl.split("_");
String lang = split[0];
String country = (split.length > 1) ? split[1] : "";
if (defaultLocale == null) {
defaultLocale = Locale.getDefault();
}
if (!Algorithms.isEmpty(lang)) {
if (!Algorithms.isEmpty(country)) {
preferredLocale = new Locale(lang, country);
} else {
preferredLocale = new Locale(lang);
}
}
Locale selectedLocale = null;
if (!Algorithms.isEmpty(lang) && !config.locale.equals(preferredLocale)) {
selectedLocale = preferredLocale;
} else if (Algorithms.isEmpty(lang) && defaultLocale != null && Locale.getDefault() != defaultLocale) {
selectedLocale = defaultLocale;
preferredLocale = null;
}
if (selectedLocale != null) {
Locale.setDefault(selectedLocale);
config.locale = selectedLocale;
config.setLayoutDirection(selectedLocale);
Resources resources = app.getBaseContext().getResources();
resources.updateConfiguration(config, resources.getDisplayMetrics());
if (android.os.Build.VERSION.SDK_INT >= 17) {
Configuration conf = new Configuration(config);
conf.locale = selectedLocale;
localizedResources = app.createConfigurationContext(conf).getResources();
}
}
}
public void setLanguage(Context context) {
if (preferredLocale != null) {
Configuration config = context.getResources().getConfiguration();
String lang = preferredLocale.getLanguage();
if (!Algorithms.isEmpty(lang) && !config.locale.getLanguage().equals(lang)) {
preferredLocale = new Locale(lang);
Locale.setDefault(preferredLocale);
config.locale = preferredLocale;
context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
} else if (Algorithms.isEmpty(lang) && defaultLocale != null && Locale.getDefault() != defaultLocale) {
Locale.setDefault(defaultLocale);
config.locale = defaultLocale;
Resources resources = app.getBaseContext().getResources();
resources.updateConfiguration(config, resources.getDisplayMetrics());
}
}
}
public Resources getLocalizedResources() {
return localizedResources;
}
public Locale getPreferredLocale() {
return preferredLocale;
}
public Locale getDefaultLocale() {
return defaultLocale;
}
public String getCountry() {
String country;
if (preferredLocale != null) {
country = preferredLocale.getCountry();
} else {
country = Locale.getDefault().getCountry();
}
return country;
}
public String getLanguage() {
String lang;
if (preferredLocale != null) {
lang = preferredLocale.getLanguage();
} else {
lang = Locale.getDefault().getLanguage();
}
if (lang != null && lang.length() > 3) {
lang = lang.substring(0, 2).toLowerCase();
}
return lang;
}
}

View file

@ -134,7 +134,7 @@ class SettingsImportTask extends BaseLoadAsyncTask<Void, Void, String> {
private SettingsImportListener getImportListener(final File file) {
return new SettingsImportListener() {
@Override
public void onSettingsImportFinished(boolean succeed, @NonNull List<SettingsItem> items) {
public void onSettingsImportFinished(boolean succeed, boolean needRestart, @NonNull List<SettingsItem> items) {
if (succeed) {
app.getRendererRegistry().updateExternalRenderers();
app.getPoiFilters().loadSelectedPoiFilters();
@ -150,7 +150,7 @@ class SettingsImportTask extends BaseLoadAsyncTask<Void, Void, String> {
}
if (!silentImport && file != null && activity != null) {
FragmentManager fm = activity.getSupportFragmentManager();
ImportCompleteFragment.showInstance(fm, items, file.getName());
ImportCompleteFragment.showInstance(fm, items, file.getName(), needRestart);
}
}
}
@ -174,7 +174,7 @@ class SettingsImportTask extends BaseLoadAsyncTask<Void, Void, String> {
final SettingsImportListener importListener = new SettingsImportListener() {
@Override
public void onSettingsImportFinished(boolean succeed, @NonNull List<SettingsItem> items) {
public void onSettingsImportFinished(boolean succeed, boolean needRestart, @NonNull List<SettingsItem> items) {
FragmentActivity activity = activityRef.get();
if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) {
progress.dismiss();

View file

@ -11,6 +11,7 @@ import net.osmand.Collator;
import net.osmand.IndexConstants;
import net.osmand.OsmAndCollator;
import net.osmand.PlatformUtil;
import net.osmand.StateChangedListener;
import net.osmand.data.LatLon;
import net.osmand.map.ITileSource;
import net.osmand.map.TileSourceManager;
@ -29,6 +30,7 @@ import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.helpers.FileNameTranslationHelper;
import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.helpers.GpxUiHelper.GPXInfo;
import net.osmand.plus.helpers.LocaleHelper;
import net.osmand.plus.helpers.SearchHistoryHelper;
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
import net.osmand.plus.mapmarkers.MapMarker;
@ -110,7 +112,7 @@ public class SettingsHelper {
private Map<File, ExportAsyncTask> exportAsyncTasks = new HashMap<>();
public interface SettingsImportListener {
void onSettingsImportFinished(boolean succeed, @NonNull List<SettingsItem> items);
void onSettingsImportFinished(boolean succeed, boolean needRestart, @NonNull List<SettingsItem> items);
}
public interface SettingsCollectListener {
@ -172,7 +174,7 @@ public class SettingsHelper {
}
}
private void finishImport(@Nullable SettingsImportListener listener, boolean success, @NonNull List<SettingsItem> items) {
private void finishImport(@Nullable SettingsImportListener listener, boolean success, @NonNull List<SettingsItem> items, boolean needRestart) {
importTask = null;
List<String> warnings = new ArrayList<>();
for (SettingsItem item : items) {
@ -182,17 +184,19 @@ public class SettingsHelper {
app.showToastMessage(AndroidUtils.formatWarnings(warnings).toString());
}
if (listener != null) {
listener.onSettingsImportFinished(success, items);
listener.onSettingsImportFinished(success, needRestart, items);
}
}
@SuppressLint("StaticFieldLeak")
private class ImportItemsAsyncTask extends AsyncTask<Void, Void, Boolean> {
private SettingsImporter importer;
private File file;
private SettingsImportListener listener;
private List<SettingsItem> items;
private final SettingsImporter importer;
private final File file;
private final SettingsImportListener listener;
private final List<SettingsItem> items;
private final StateChangedListener<String> localeListener;
private boolean needRestart = false;
ImportItemsAsyncTask(@NonNull File file,
@Nullable SettingsImportListener listener,
@ -201,6 +205,17 @@ public class SettingsHelper {
this.file = file;
this.listener = listener;
this.items = items;
localeListener = new StateChangedListener<String>() {
@Override
public void stateChanged(String change) {
needRestart = true;
}
};
}
@Override
protected void onPreExecute() {
app.getSettings().PREFERRED_LOCALE.addListener(localeListener);
}
@Override
@ -218,7 +233,8 @@ public class SettingsHelper {
@Override
protected void onPostExecute(Boolean success) {
finishImport(listener, success, items);
app.getSettings().PREFERRED_LOCALE.removeListener(localeListener);
finishImport(listener, success, items, needRestart);
}
}
@ -339,7 +355,7 @@ public class SettingsHelper {
protected void onPreExecute() {
ImportAsyncTask importTask = SettingsHelper.this.importTask;
if (importTask != null && !importTask.importDone) {
finishImport(importListener, false, items);
finishImport(importListener, false, items, false);
}
SettingsHelper.this.importTask = this;
}

View file

@ -202,7 +202,7 @@ public class ConfigureProfileFragment extends BaseSettingsFragment implements Co
private void importBackupSettingsItems(File file, List<SettingsItem> items) {
app.getSettingsHelper().importSettings(file, items, "", 1, new SettingsHelper.SettingsImportListener() {
@Override
public void onSettingsImportFinished(boolean succeed, @NonNull List<SettingsItem> items) {
public void onSettingsImportFinished(boolean succeed, boolean needRestart, @NonNull List<SettingsItem> items) {
app.showToastMessage(R.string.profile_prefs_reset_successful);
updateCopiedOrResetPrefs();
}

View file

@ -108,7 +108,7 @@ public class GlobalSettingsFragment extends BaseSettingsFragment
Activity activity = getActivity();
OsmandApplication app = getMyApplication();
if (app != null && activity != null) {
app.checkPreferredLocale();
app.getLocaleHelper().checkPreferredLocale();
app.restartApp(activity);
}
} else if (prefId.equals(settings.SPEED_CAMERAS_UNINSTALLED.getId())) {

View file

@ -15,6 +15,7 @@ import android.widget.TextView;
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@ -28,6 +29,7 @@ import net.osmand.plus.audionotes.AudioVideoNotesPlugin;
import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.dashboard.DashboardOnMap;
import net.osmand.plus.dialogs.SelectMapStyleBottomSheetDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.myplaces.FavoritesActivity;
import net.osmand.plus.osmedit.OsmEditingPlugin;
import net.osmand.plus.quickaction.QuickActionListFragment;
@ -50,14 +52,16 @@ public class ImportCompleteFragment extends BaseOsmAndFragment {
private RecyclerView recyclerView;
private List<SettingsItem> settingsItems;
private String fileName;
private boolean needRestart;
private boolean nightMode;
public static void showInstance(FragmentManager fm, @NonNull List<SettingsItem> settingsItems,
@NonNull String fileName) {
@NonNull String fileName, boolean needRestart) {
ImportCompleteFragment fragment = new ImportCompleteFragment();
fragment.setSettingsItems(settingsItems);
fragment.setFileName(fileName);
fragment.setRetainInstance(true);
fragment.setNeedRestart(needRestart);
fm.beginTransaction()
.replace(R.id.fragmentContainer, fragment, TAG)
.addToBackStack(SETTINGS_LIST_TAG)
@ -97,6 +101,9 @@ public class ImportCompleteFragment extends BaseOsmAndFragment {
dismissFragment();
}
});
if (needRestart) {
setupRestartButton(root);
}
if (Build.VERSION.SDK_INT >= 21) {
AndroidUtils.addStatusBarPadding21v(app, root);
}
@ -239,6 +246,25 @@ public class ImportCompleteFragment extends BaseOsmAndFragment {
}
}
private void setupRestartButton(View root) {
View buttonsDivider = root.findViewById(R.id.buttons_divider);
View buttonContainer = root.findViewById(R.id.button_restart_container);
AndroidUiHelper.setVisibility(View.VISIBLE, buttonsDivider, buttonContainer);
TextView btnRestart = root.findViewById(R.id.button_restart);
btnRestart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentActivity activity = getActivity();
if (activity instanceof MapActivity) {
MapActivity.doRestart(activity);
} else {
android.os.Process.killProcess(android.os.Process.myPid());
}
}
});
}
@Override
public int getStatusBarColorId() {
return nightMode ? R.color.status_bar_color_dark : R.color.status_bar_color_light;
@ -251,4 +277,8 @@ public class ImportCompleteFragment extends BaseOsmAndFragment {
public void setFileName(String fileName) {
this.fileName = fileName;
}
public void setNeedRestart(boolean needRestart) {
this.needRestart = needRestart;
}
}

View file

@ -155,7 +155,7 @@ public class ImportSettingsFragment extends BaseSettingsListFragment {
public SettingsHelper.SettingsImportListener getImportListener() {
return new SettingsHelper.SettingsImportListener() {
@Override
public void onSettingsImportFinished(boolean succeed, @NonNull List<SettingsItem> items) {
public void onSettingsImportFinished(boolean succeed, boolean needRestart, @NonNull List<SettingsItem> items) {
if (succeed) {
app.getRendererRegistry().updateExternalRenderers();
AppInitializer.loadRoutingFiles(app, null);
@ -166,7 +166,7 @@ public class ImportSettingsFragment extends BaseSettingsListFragment {
}
FragmentManager fm = getFragmentManager();
if (fm != null && file != null) {
ImportCompleteFragment.showInstance(fm, items, file.getName());
ImportCompleteFragment.showInstance(fm, items, file.getName(), needRestart);
}
}
}

View file

@ -40,7 +40,7 @@ public class WebViewEx extends WebView {
// also see: https://gist.github.com/amake/0ac7724681ac1c178c6f95a5b09f03ce
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
OsmandApplication app = (OsmandApplication) ctx.getApplicationContext();
app.checkPreferredLocale();
app.getLocaleHelper().checkPreferredLocale();
ctx.getResources().updateConfiguration(
new Configuration(app.getResources().getConfiguration()),
ctx.getResources().getDisplayMetrics());

View file

@ -71,7 +71,7 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv
nightMode = !settings.isLightContent();
int themeId = nightMode ? R.style.OsmandDarkTheme_NoActionbar : R.style.OsmandLightTheme_NoActionbar_LightStatusBar;
app.setLanguage(this);
app.getLocaleHelper().setLanguage(this);
setTheme(themeId);
super.onCreate(savedInstanceState);