This commit is contained in:
Philipp Crocoll
2021-11-11 12:12:24 +01:00
parent adb0865aa7
commit 81c4477453
22 changed files with 273 additions and 124 deletions

View File

@@ -66,16 +66,16 @@ namespace keepass2android
public override string GetTitle(string key) public override string GetTitle(string key)
{ {
if (key == strVisible) if (key == strVisible)
return Application.Context.GetString(Resource.String.Visible_title); return LocaleManager.LocalizedAppContext.GetString(Resource.String.Visible_title);
if (key == strEnabled) if (key == strEnabled)
return Application.Context.GetString(Resource.String.child_db_Enabled_title); return LocaleManager.LocalizedAppContext.GetString(Resource.String.child_db_Enabled_title);
if (key == strUiKeyFile) if (key == strUiKeyFile)
return Application.Context.GetString(Resource.String.keyfile_heading); return LocaleManager.LocalizedAppContext.GetString(Resource.String.keyfile_heading);
if (key == strUiDatabaseFile) if (key == strUiDatabaseFile)
return Application.Context.GetString(Resource.String.database_file_heading); return LocaleManager.LocalizedAppContext.GetString(Resource.String.database_file_heading);
if (key.StartsWith(strUiIfDevice)) if (key.StartsWith(strUiIfDevice))
{ {
return Application.Context.GetString(Resource.String.if_device_text,new Object[]{key.Substring(strUiIfDevice.Length)}); return LocaleManager.LocalizedAppContext.GetString(Resource.String.if_device_text,new Object[]{key.Substring(strUiIfDevice.Length)});
} }
return key; return key;
} }

View File

@@ -459,7 +459,7 @@ namespace keepass2android
_activity.StartActivityForResult(i, _requestCode); _activity.StartActivityForResult(i, _requestCode);
#else #else
Toast.MakeText(Application.Context, "File chooser is excluded!", ToastLength.Long).Show(); Toast.MakeText(LocaleManager.LocalizedAppContext, "File chooser is excluded!", ToastLength.Long).Show();
#endif #endif
return true; return true;
} }

View File

@@ -1250,7 +1250,7 @@ namespace keepass2android
{ {
Handler.Post(() => Handler.Post(() =>
{ {
Toast.MakeText(ActiveActivity ?? Application.Context, "Unrecoverable error: " + Message, ToastLength.Long).Show(); Toast.MakeText(ActiveActivity ?? LocaleManager.LocalizedAppContext, "Unrecoverable error: " + Message, ToastLength.Long).Show();
}); });
App.Kp2a.Lock(false); App.Kp2a.Lock(false);

View File

@@ -61,7 +61,7 @@ namespace keepass2android
{ {
if (_thisDevice != null) if (_thisDevice != null)
return _thisDevice; return _thisDevice;
String android_id = Settings.Secure.GetString(Application.Context.ContentResolver, Settings.Secure.AndroidId); String android_id = Settings.Secure.GetString(LocaleManager.LocalizedAppContext.ContentResolver, Settings.Secure.AndroidId);
string deviceName = Build.Manufacturer+" "+Build.Model; string deviceName = Build.Manufacturer+" "+Build.Model;
_thisDevice = deviceName + " (" + android_id + ")"; _thisDevice = deviceName + " (" + android_id + ")";
@@ -315,7 +315,7 @@ namespace keepass2android
try { ck.AddUserKey(new KcpKeyFile(strAbs)); } try { ck.AddUserKey(new KcpKeyFile(strAbs)); }
catch (InvalidOperationException) catch (InvalidOperationException)
{ {
Toast.MakeText(Application.Context,Resource.String.error_adding_keyfile,ToastLength.Long).Show(); Toast.MakeText(LocaleManager.LocalizedAppContext,Resource.String.error_adding_keyfile,ToastLength.Long).Show();
return false; return false;
} }
catch (Exception) { throw; } catch (Exception) { throw; }

View File

@@ -28,6 +28,10 @@ namespace keepass2android
public abstract class LifecycleAwareActivity : AndroidX.AppCompat.App.AppCompatActivity public abstract class LifecycleAwareActivity : AndroidX.AppCompat.App.AppCompatActivity
{ {
protected override void AttachBaseContext(Context baseContext)
{
base.AttachBaseContext(LocaleManager.setLocale(baseContext));
}
protected LifecycleAwareActivity (IntPtr javaReference, JniHandleOwnership transfer) protected LifecycleAwareActivity (IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer) : base(javaReference, transfer)
{ {
@@ -86,7 +90,9 @@ namespace keepass2android
protected override void OnCreate(Bundle bundle) protected override void OnCreate(Bundle bundle)
{ {
base.OnCreate(bundle); base.OnCreate(bundle);
Kp2aLog.Log(ClassName+".OnCreate" + " " + ID); Kp2aLog.Log(ClassName+".OnCreate" + " " + ID);
Kp2aLog.Log(ClassName+":apptask="+Intent.GetStringExtra("KP2A_APP_TASK_TYPE") + " " + ID); Kp2aLog.Log(ClassName+":apptask="+Intent.GetStringExtra("KP2A_APP_TASK_TYPE") + " " + ID);
} }

View File

@@ -37,7 +37,7 @@ namespace keepass2android
}; };
FindViewById<Button>(Resource.Id.disable_secure_screen_check).Click += (sender, args) => FindViewById<Button>(Resource.Id.disable_secure_screen_check).Click += (sender, args) =>
{ {
var prefs = PreferenceManager.GetDefaultSharedPreferences(Application.Context); var prefs = PreferenceManager.GetDefaultSharedPreferences(LocaleManager.LocalizedAppContext);
prefs.Edit() prefs.Edit()
.PutBoolean("no_secure_display_check", true) .PutBoolean("no_secure_display_check", true)
.Commit(); .Commit();

View File

@@ -67,6 +67,7 @@
<string name="omitbackup_key">omitbackup</string> <string name="omitbackup_key">omitbackup</string>
<string name="list_size_key">list_size</string> <string name="list_size_key">list_size</string>
<string name="design_key">design_key</string> <string name="design_key">design_key</string>
<string name="app_language_pref_key">app_language_pref_key</string>
<string name="sort_key_old">sort_key</string> <string name="sort_key_old">sort_key</string>
<string name="sort_key">sort_key_new</string> <string name="sort_key">sort_key_new</string>
<string name="sortgroups_key">sortgroups_key</string> <string name="sortgroups_key">sortgroups_key</string>

View File

@@ -81,6 +81,7 @@
<string name="copy_password">Select to copy password to clipboard</string> <string name="copy_password">Select to copy password to clipboard</string>
<string name="copy_totp">Select to copy TOTP to clipboard</string> <string name="copy_totp">Select to copy TOTP to clipboard</string>
<string name="available_through_keyboard">Entry is available through KP2A Keyboard</string> <string name="available_through_keyboard">Entry is available through KP2A Keyboard</string>
<string name="app_language_pref_title">App language</string>
<string name="entry_is_available">is available</string> <string name="entry_is_available">is available</string>
<string name="not_possible_im_picker">Could not open dialog to select input method. Please activate keyboard manually.</string> <string name="not_possible_im_picker">Could not open dialog to select input method. Please activate keyboard manually.</string>
<string name="please_activate_keyboard">Please enable the Keepass2Android keyboard in your system settings.</string> <string name="please_activate_keyboard">Please enable the Keepass2Android keyboard in your system settings.</string>
@@ -92,6 +93,7 @@
<string name="disclaimer_formal">Keepass2Android comes with ABSOLUTELY NO WARRANTY; This is free software, and you are welcome to redistribute it under the conditions of the GPL version 2 or later.</string> <string name="disclaimer_formal">Keepass2Android comes with ABSOLUTELY NO WARRANTY; This is free software, and you are welcome to redistribute it under the conditions of the GPL version 2 or later.</string>
<string name="ellipsis">\u2026</string> <string name="ellipsis">\u2026</string>
<string name="copy_to_clipboard">Copy to clipboard</string> <string name="copy_to_clipboard">Copy to clipboard</string>
<string name="SystemLanguage">System language</string>
<string name="fingerprint_description">Please authenticate to continue</string> <string name="fingerprint_description">Please authenticate to continue</string>
<string name="fingerprint_fatal">Cannot setup Biometric Unlock:</string> <string name="fingerprint_fatal">Cannot setup Biometric Unlock:</string>
<string name="fingerprint_not_recognized">Biometric authentication failed. Try again</string> <string name="fingerprint_not_recognized">Biometric authentication failed. Try again</string>
@@ -824,6 +826,7 @@
<string-array name="ChangeLog_1_09b"> <string-array name="ChangeLog_1_09b">
<item>Fix disappearing autofill prompt in Firefox</item> <item>Fix disappearing autofill prompt in Firefox</item>
<item>Integrate autofill suggestions with keyboard (requires Android 11+)</item> <item>Integrate autofill suggestions with keyboard (requires Android 11+)</item>
<item>Allow to change app language in settings</item>
</string-array> </string-array>

View File

@@ -280,6 +280,12 @@
android:dialogTitle="@string/design_title" android:dialogTitle="@string/design_title"
android:defaultValue="@string/design_default"/> android:defaultValue="@string/design_default"/>
<ListPreference
android:key="@string/app_language_pref_key"
android:title="@string/app_language_pref_title"
android:dialogTitle="@string/app_language_pref_title"
/>
<CheckBoxPreference <CheckBoxPreference
android:enabled="true" android:enabled="true"

View File

@@ -26,7 +26,7 @@ namespace keepass2android
return null; return null;
foreach (ITotpPluginAdapter adapter in _pluginAdapters) foreach (ITotpPluginAdapter adapter in _pluginAdapters)
{ {
TotpData totpData = adapter.GetTotpData(entry.OutputStrings.ToDictionary(pair => StrUtil.SafeXmlString(pair.Key), pair => pair.Value.ReadString()), Application.Context, false); TotpData totpData = adapter.GetTotpData(entry.OutputStrings.ToDictionary(pair => StrUtil.SafeXmlString(pair.Key), pair => pair.Value.ReadString()), LocaleManager.LocalizedAppContext, false);
if (totpData.IsTotpEntry) if (totpData.IsTotpEntry)
{ {
return totpData; return totpData;
@@ -47,7 +47,7 @@ namespace keepass2android
{ {
TotpData totpData = adapter.GetTotpData( TotpData totpData = adapter.GetTotpData(
App.Kp2a.LastOpenedEntry.OutputStrings.ToDictionary(pair => StrUtil.SafeXmlString(pair.Key), App.Kp2a.LastOpenedEntry.OutputStrings.ToDictionary(pair => StrUtil.SafeXmlString(pair.Key),
pair => pair.Value.ReadString()), Application.Context, false); pair => pair.Value.ReadString()), LocaleManager.LocalizedAppContext, false);
if (totpData.IsTotpEntry) if (totpData.IsTotpEntry)
{ {
return adapter; return adapter;
@@ -67,7 +67,7 @@ namespace keepass2android
{ {
var adapter = TryGetAdapter(App.Kp2a.LastOpenedEntry); var adapter = TryGetAdapter(App.Kp2a.LastOpenedEntry);
if (adapter != null) if (adapter != null)
new UpdateTotpTimerTask(Application.Context, adapter).Run(); new UpdateTotpTimerTask(LocaleManager.LocalizedAppContext, adapter).Run();
} }
} }
} }

View File

@@ -41,12 +41,79 @@ using KeePassLib.Security;
using KeePassLib.Serialization; using KeePassLib.Serialization;
using Uri = Android.Net.Uri; using Uri = Android.Net.Uri;
namespace keepass2android namespace keepass2android
{ {
public class LocaleManager
{
public static Context LocalizedAppContext
{
get
{
//the standard way of setting locale on the app context is through Application.AttachBaseContext,
//but because of https://bugzilla.xamarin.com/11/11182/bug.html this doesn't work
return setLocale(Application.Context);
}
}
public static Context setLocale(Context c)
{
return setNewLocale(c, getLanguage(c));
}
public static Context setNewLocale(Context c, String language)
{
return updateResources(c, language);
}
static string _language;
public static string Language
{
get { return _language; }
set { _language = value;languageLoaded = true;
}
}
static bool languageLoaded = false;
public static String getLanguage(Context c)
{
if (!languageLoaded)
{
var language = PreferenceManager.GetDefaultSharedPreferences(c).GetString(c.GetString(Resource.String.app_language_pref_key), null);
Language = language;
}
return Language;
}
private static Context updateResources(Context context, String language)
{
if (language == null)
return context;
Java.Util.Locale locale = new Java.Util.Locale(language);
Java.Util.Locale.Default = locale;
Resources res = context.Resources;
Configuration config = new Configuration(res.Configuration);
if ((int)Build.VERSION.SdkInt >= 17)
{
config.SetLocale(locale);
context = context.CreateConfigurationContext(config);
}
else
{
config.Locale = locale;
res.UpdateConfiguration(config, res.DisplayMetrics);
}
return context;
}
}
public class Util { public class Util {
public const String KeyFilename = "fileName";
public const String KeyFilename = "fileName";
public const String KeyServerusername = "serverCredUser"; public const String KeyServerusername = "serverCredUser";
public const String KeyServerpassword = "serverCredPwd"; public const String KeyServerpassword = "serverCredPwd";
public const String KeyServercredmode = "serverCredRememberMode"; public const String KeyServercredmode = "serverCredRememberMode";
@@ -253,7 +320,7 @@ namespace keepass2android
* @return True if an Intent with the specified action can be sent and * @return True if an Intent with the specified action can be sent and
* responded to, false otherwise. * responded to, false otherwise.
*/ */
static bool IsIntentAvailable(Context context, String action, String type, List<String> categories ) static bool IsIntentAvailable(Context context, String action, String type, List<String> categories )
{ {
PackageManager packageManager = context.PackageManager; PackageManager packageManager = context.PackageManager;
Intent intent = new Intent(action); Intent intent = new Intent(action);

View File

@@ -109,7 +109,10 @@ namespace keepass2android
/// </summary> /// </summary>
public class Kp2aApp: IKp2aApp, ICacheSupervisor public class Kp2aApp: IKp2aApp, ICacheSupervisor
{ {
public void Lock(bool allowQuickUnlock = true, bool lockWasTriggeredByTimeout = false)
public void Lock(bool allowQuickUnlock = true, bool lockWasTriggeredByTimeout = false)
{ {
if (OpenDatabases.Any()) if (OpenDatabases.Any())
{ {
@@ -122,7 +125,7 @@ namespace keepass2android
Kp2aLog.Log("QuickLocking database"); Kp2aLog.Log("QuickLocking database");
QuickLocked = true; QuickLocked = true;
LastOpenedEntry = null; LastOpenedEntry = null;
BroadcastDatabaseAction(Application.Context, Strings.ActionLockDatabase); BroadcastDatabaseAction(LocaleManager.LocalizedAppContext, Strings.ActionLockDatabase);
} }
else else
{ {
@@ -133,7 +136,7 @@ namespace keepass2android
{ {
Kp2aLog.Log("Locking database"); Kp2aLog.Log("Locking database");
BroadcastDatabaseAction(Application.Context, Strings.ActionCloseDatabase); BroadcastDatabaseAction(LocaleManager.LocalizedAppContext, Strings.ActionCloseDatabase);
// Couldn't quick-lock, so unload database(s) instead // Couldn't quick-lock, so unload database(s) instead
_openAttempts.Clear(); _openAttempts.Clear();
@@ -153,7 +156,7 @@ namespace keepass2android
var intent = new Intent(Intents.DatabaseLocked); var intent = new Intent(Intents.DatabaseLocked);
if (lockWasTriggeredByTimeout) if (lockWasTriggeredByTimeout)
intent.PutExtra("ByTimeout", true); intent.PutExtra("ByTimeout", true);
Application.Context.SendBroadcast(intent); LocaleManager.LocalizedAppContext.SendBroadcast(intent);
} }
@@ -178,8 +181,8 @@ namespace keepass2android
public Database LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compositeKey, ProgressDialogStatusLogger statusLogger, IDatabaseFormat databaseFormat, bool makeCurrent) public Database LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compositeKey, ProgressDialogStatusLogger statusLogger, IDatabaseFormat databaseFormat, bool makeCurrent)
{ {
var prefs = PreferenceManager.GetDefaultSharedPreferences(Application.Context); var prefs = PreferenceManager.GetDefaultSharedPreferences(LocaleManager.LocalizedAppContext);
var createBackup = prefs.GetBoolean(Application.Context.GetString(Resource.String.CreateBackups_key), true) var createBackup = prefs.GetBoolean(LocaleManager.LocalizedAppContext.GetString(Resource.String.CreateBackups_key), true)
&& !(new LocalFileStorage(this).IsLocalBackup(ioConnectionInfo)); && !(new LocalFileStorage(this).IsLocalBackup(ioConnectionInfo));
MemoryStream backupCopy = new MemoryStream(); MemoryStream backupCopy = new MemoryStream();
@@ -216,8 +219,8 @@ namespace keepass2android
if (createBackup) if (createBackup)
{ {
statusLogger.UpdateMessage(Application.Context.GetString(Resource.String.UpdatingBackup)); statusLogger.UpdateMessage(LocaleManager.LocalizedAppContext.GetString(Resource.String.UpdatingBackup));
Java.IO.File internalDirectory = IoUtil.GetInternalDirectory(Application.Context); Java.IO.File internalDirectory = IoUtil.GetInternalDirectory(LocaleManager.LocalizedAppContext);
string baseDisplayName = App.Kp2a.GetFileStorage(ioConnectionInfo).GetDisplayName(ioConnectionInfo); string baseDisplayName = App.Kp2a.GetFileStorage(ioConnectionInfo).GetDisplayName(ioConnectionInfo);
string targetPath = baseDisplayName; string targetPath = baseDisplayName;
var charsToRemove = "|\\?*<\":>+[]/'"; var charsToRemove = "|\\?*<\":>+[]/'";
@@ -242,7 +245,7 @@ namespace keepass2android
Java.Lang.Object baseIocDisplayName = baseDisplayName; Java.Lang.Object baseIocDisplayName = baseDisplayName;
string keyfile = App.Kp2a.FileDbHelper.GetKeyFileForFile(ioConnectionInfo.Path); string keyfile = App.Kp2a.FileDbHelper.GetKeyFileForFile(ioConnectionInfo.Path);
App.Kp2a.StoreOpenedFileAsRecent(targetIoc, keyfile, false, Application.Context. App.Kp2a.StoreOpenedFileAsRecent(targetIoc, keyfile, false, LocaleManager.LocalizedAppContext.
GetString(Resource.String.LocalBackupOf, new Java.Lang.Object[]{baseIocDisplayName})); GetString(Resource.String.LocalBackupOf, new Java.Lang.Object[]{baseIocDisplayName}));
prefs.Edit() prefs.Edit()
@@ -298,13 +301,13 @@ namespace keepass2android
UpdateOngoingNotification(); UpdateOngoingNotification();
BroadcastDatabaseAction(Application.Context, Strings.ActionUnlockDatabase); BroadcastDatabaseAction(LocaleManager.LocalizedAppContext, Strings.ActionUnlockDatabase);
} }
public void UpdateOngoingNotification() public void UpdateOngoingNotification()
{ {
// Start or update the notification icon service to reflect the current state // Start or update the notification icon service to reflect the current state
var ctx = Application.Context; var ctx = LocaleManager.LocalizedAppContext;
if (DatabaseIsUnlocked || QuickLocked) if (DatabaseIsUnlocked || QuickLocked)
{ {
ContextCompat.StartForegroundService(ctx, new Intent(ctx, typeof(OngoingNotificationsService))); ContextCompat.StartForegroundService(ctx, new Intent(ctx, typeof(OngoingNotificationsService)));
@@ -333,7 +336,7 @@ namespace keepass2android
//Set KeyLength of QuickUnlock at time of enabling. //Set KeyLength of QuickUnlock at time of enabling.
//This is important to not allow an attacker to set the length to 1 when QuickUnlock is started already. //This is important to not allow an attacker to set the length to 1 when QuickUnlock is started already.
var ctx = Application.Context; var ctx = LocaleManager.LocalizedAppContext;
var prefs = PreferenceManager.GetDefaultSharedPreferences(ctx); var prefs = PreferenceManager.GetDefaultSharedPreferences(ctx);
QuickUnlockKeyLength = Math.Max(1, int.Parse(prefs.GetString(ctx.GetString(Resource.String.QuickUnlockLength_key), ctx.GetString(Resource.String.QuickUnlockLength_default)))); QuickUnlockKeyLength = Math.Max(1, int.Parse(prefs.GetString(ctx.GetString(Resource.String.QuickUnlockLength_key), ctx.GetString(Resource.String.QuickUnlockLength_default))));
} }
@@ -429,7 +432,7 @@ namespace keepass2android
public bool GetBooleanPreference(PreferenceKey key) public bool GetBooleanPreference(PreferenceKey key)
{ {
Context ctx = Application.Context; Context ctx = LocaleManager.LocalizedAppContext;
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(ctx); ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(ctx);
switch (key) switch (key)
{ {
@@ -504,7 +507,7 @@ namespace keepass2android
var field = typeof(Resource.String).GetField(key); var field = typeof(Resource.String).GetField(key);
if (field == null) if (field == null)
throw new Exception("Invalid key " + key); throw new Exception("Invalid key " + key);
return Application.Context.GetString((int)field.GetValue(null)); return LocaleManager.LocalizedAppContext.GetString((int)field.GetValue(null));
} }
public Drawable GetStorageIcon(string protocolId) public Drawable GetStorageIcon(string protocolId)
@@ -523,7 +526,7 @@ namespace keepass2android
var field = typeof(Resource.Drawable).GetField(key); var field = typeof(Resource.Drawable).GetField(key);
if (field == null) if (field == null)
throw new Exception("Invalid key " + key); throw new Exception("Invalid key " + key);
return Application.Context.Resources.GetDrawable((int)field.GetValue(null)); return LocaleManager.LocalizedAppContext.Resources.GetDrawable((int)field.GetValue(null));
} }
public void AskYesNoCancel(UiStringKey titleKey, UiStringKey messageKey, EventHandler<DialogClickEventArgs> yesHandler, EventHandler<DialogClickEventArgs> noHandler, EventHandler<DialogClickEventArgs> cancelHandler, Context ctx, string messageSuffix) public void AskYesNoCancel(UiStringKey titleKey, UiStringKey messageKey, EventHandler<DialogClickEventArgs> yesHandler, EventHandler<DialogClickEventArgs> noHandler, EventHandler<DialogClickEventArgs> cancelHandler, Context ctx, string messageSuffix)
@@ -667,7 +670,7 @@ namespace keepass2android
if (DatabaseCacheEnabled && allowCache) if (DatabaseCacheEnabled && allowCache)
{ {
fileStorage = new CachingFileStorage(innerFileStorage, Application.Context, this); fileStorage = new CachingFileStorage(innerFileStorage, LocaleManager.LocalizedAppContext, this);
} }
else else
{ {
@@ -705,20 +708,20 @@ namespace keepass2android
_fileStorages = new List<IFileStorage> _fileStorages = new List<IFileStorage>
{ {
new AndroidContentStorage(Application.Context), new AndroidContentStorage(LocaleManager.LocalizedAppContext),
#if !EXCLUDE_JAVAFILESTORAGE #if !EXCLUDE_JAVAFILESTORAGE
#if !NoNet #if !NoNet
new DropboxFileStorage(Application.Context, this), new DropboxFileStorage(LocaleManager.LocalizedAppContext, this),
new DropboxAppFolderFileStorage(Application.Context, this), new DropboxAppFolderFileStorage(LocaleManager.LocalizedAppContext, this),
GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(Application.Context)==ConnectionResult.Success ? new GoogleDriveFileStorage(Application.Context, this) : null, GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(LocaleManager.LocalizedAppContext)==ConnectionResult.Success ? new GoogleDriveFileStorage(LocaleManager.LocalizedAppContext, this) : null,
new OneDriveFileStorage(Application.Context, this), new OneDriveFileStorage(LocaleManager.LocalizedAppContext, this),
new OneDrive2FullFileStorage(), new OneDrive2FullFileStorage(),
new OneDrive2MyFilesFileStorage(), new OneDrive2MyFilesFileStorage(),
new OneDrive2AppFolderFileStorage(), new OneDrive2AppFolderFileStorage(),
new SftpFileStorage(Application.Context, this), new SftpFileStorage(LocaleManager.LocalizedAppContext, this),
new NetFtpFileStorage(Application.Context, this), new NetFtpFileStorage(LocaleManager.LocalizedAppContext, this),
new WebDavFileStorage(this), new WebDavFileStorage(this),
new PCloudFileStorage(Application.Context, this), new PCloudFileStorage(LocaleManager.LocalizedAppContext, this),
//new LegacyWebDavStorage(this), //new LegacyWebDavStorage(this),
//new LegacyFtpStorage(this), //new LegacyFtpStorage(this),
#endif #endif
@@ -783,12 +786,12 @@ namespace keepass2android
private ValidationMode GetValidationMode() private ValidationMode GetValidationMode()
{ {
var prefs = PreferenceManager.GetDefaultSharedPreferences(Application.Context); var prefs = PreferenceManager.GetDefaultSharedPreferences(LocaleManager.LocalizedAppContext);
ValidationMode validationMode = ValidationMode.Warn; ValidationMode validationMode = ValidationMode.Warn;
string strValMode = prefs.GetString(Application.Context.Resources.GetString(Resource.String.AcceptAllServerCertificates_key), string strValMode = prefs.GetString(LocaleManager.LocalizedAppContext.Resources.GetString(Resource.String.AcceptAllServerCertificates_key),
Application.Context.Resources.GetString(Resource.String.AcceptAllServerCertificates_default)); LocaleManager.LocalizedAppContext.Resources.GetString(Resource.String.AcceptAllServerCertificates_default));
if (strValMode == "IGNORE") if (strValMode == "IGNORE")
validationMode = ValidationMode.Ignore; validationMode = ValidationMode.Ignore;
@@ -801,8 +804,8 @@ namespace keepass2android
{ {
get get
{ {
var prefs = PreferenceManager.GetDefaultSharedPreferences(Application.Context); var prefs = PreferenceManager.GetDefaultSharedPreferences(LocaleManager.LocalizedAppContext);
return prefs.GetBoolean(Application.Context.GetString(Resource.String.CheckForDuplicateUuids_key), true); return prefs.GetBoolean(LocaleManager.LocalizedAppContext.GetString(Resource.String.CheckForDuplicateUuids_key), true);
} }
} }
@@ -849,7 +852,7 @@ namespace keepass2android
#endif #endif
private void ShowValidationWarning(string error) private void ShowValidationWarning(string error)
{ {
ShowToast(Application.Context.GetString(Resource.String.CertificateWarning, error)); ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.CertificateWarning, error));
} }
@@ -901,7 +904,7 @@ namespace keepass2android
internal void ShowToast(string message) internal void ShowToast(string message)
{ {
var handler = new Handler(Looper.MainLooper); var handler = new Handler(Looper.MainLooper);
handler.Post(() => { var toast = Toast.MakeText(Application.Context, message, ToastLength.Long); handler.Post(() => { var toast = Toast.MakeText(LocaleManager.LocalizedAppContext, message, ToastLength.Long);
toast.SetGravity(GravityFlags.Center, 0, 0); toast.SetGravity(GravityFlags.Center, 0, 0);
toast.Show(); toast.Show();
}); });
@@ -910,7 +913,7 @@ namespace keepass2android
public void CouldntSaveToRemote(IOConnectionInfo ioc, Exception e) public void CouldntSaveToRemote(IOConnectionInfo ioc, Exception e)
{ {
var errorMessage = GetErrorMessageForFileStorageException(e); var errorMessage = GetErrorMessageForFileStorageException(e);
ShowToast(Application.Context.GetString(Resource.String.CouldNotSaveToRemote, errorMessage)); ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.CouldNotSaveToRemote, errorMessage));
} }
private string GetErrorMessageForFileStorageException(Exception e) private string GetErrorMessageForFileStorageException(Exception e)
@@ -928,33 +931,33 @@ namespace keepass2android
public void CouldntOpenFromRemote(IOConnectionInfo ioc, Exception ex) public void CouldntOpenFromRemote(IOConnectionInfo ioc, Exception ex)
{ {
var errorMessage = GetErrorMessageForFileStorageException(ex); var errorMessage = GetErrorMessageForFileStorageException(ex);
ShowToast(Application.Context.GetString(Resource.String.CouldNotLoadFromRemote, errorMessage)); ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.CouldNotLoadFromRemote, errorMessage));
} }
public void UpdatedCachedFileOnLoad(IOConnectionInfo ioc) public void UpdatedCachedFileOnLoad(IOConnectionInfo ioc)
{ {
ShowToast(Application.Context.GetString(Resource.String.UpdatedCachedFileOnLoad, ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.UpdatedCachedFileOnLoad,
new Java.Lang.Object[] { Application.Context.GetString(Resource.String.database_file) })); new Java.Lang.Object[] { LocaleManager.LocalizedAppContext.GetString(Resource.String.database_file) }));
} }
public void UpdatedRemoteFileOnLoad(IOConnectionInfo ioc) public void UpdatedRemoteFileOnLoad(IOConnectionInfo ioc)
{ {
ShowToast(Application.Context.GetString(Resource.String.UpdatedRemoteFileOnLoad)); ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.UpdatedRemoteFileOnLoad));
} }
public void NotifyOpenFromLocalDueToConflict(IOConnectionInfo ioc) public void NotifyOpenFromLocalDueToConflict(IOConnectionInfo ioc)
{ {
ShowToast(Application.Context.GetString(Resource.String.NotifyOpenFromLocalDueToConflict)); ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.NotifyOpenFromLocalDueToConflict));
} }
public void LoadedFromRemoteInSync(IOConnectionInfo ioc) public void LoadedFromRemoteInSync(IOConnectionInfo ioc)
{ {
ShowToast(Application.Context.GetString(Resource.String.LoadedFromRemoteInSync)); ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.LoadedFromRemoteInSync));
} }
public void ClearOfflineCache() public void ClearOfflineCache()
{ {
new CachingFileStorage(new LocalFileStorage(this), Application.Context, this).ClearCache(); new CachingFileStorage(new LocalFileStorage(this), LocaleManager.LocalizedAppContext, this).ClearCache();
} }
public IFileStorage GetFileStorage(string protocolId) public IFileStorage GetFileStorage(string protocolId)
@@ -978,7 +981,7 @@ namespace keepass2android
if (DatabaseCacheEnabled) if (DatabaseCacheEnabled)
{ {
return new OtpAuxCachingFileStorage(innerFileStorage, Application.Context, new OtpAuxCacheSupervisor(this)); return new OtpAuxCachingFileStorage(innerFileStorage, LocaleManager.LocalizedAppContext, new OtpAuxCacheSupervisor(this));
} }
else else
{ {
@@ -991,8 +994,8 @@ namespace keepass2android
{ {
get get
{ {
var prefs = PreferenceManager.GetDefaultSharedPreferences(Application.Context); var prefs = PreferenceManager.GetDefaultSharedPreferences(LocaleManager.LocalizedAppContext);
bool cacheEnabled = prefs.GetBoolean(Application.Context.Resources.GetString(Resource.String.UseOfflineCache_key), bool cacheEnabled = prefs.GetBoolean(LocaleManager.LocalizedAppContext.Resources.GetString(Resource.String.UseOfflineCache_key),
#if NoNet #if NoNet
false false
#else #else
@@ -1007,14 +1010,14 @@ namespace keepass2android
{ {
get get
{ {
var prefs = PreferenceManager.GetDefaultSharedPreferences(Application.Context); var prefs = PreferenceManager.GetDefaultSharedPreferences(LocaleManager.LocalizedAppContext);
return prefs.GetBoolean(Application.Context.GetString(Resource.String.OfflineMode_key), false); return prefs.GetBoolean(LocaleManager.LocalizedAppContext.GetString(Resource.String.OfflineMode_key), false);
} }
set set
{ {
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(Application.Context); ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(LocaleManager.LocalizedAppContext);
ISharedPreferencesEditor edit = prefs.Edit(); ISharedPreferencesEditor edit = prefs.Edit();
edit.PutBoolean(Application.Context.GetString(Resource.String.OfflineMode_key), value); edit.PutBoolean(LocaleManager.LocalizedAppContext.GetString(Resource.String.OfflineMode_key), value);
edit.Commit(); edit.Commit();
} }
@@ -1035,9 +1038,9 @@ namespace keepass2android
public void OnScreenOff() public void OnScreenOff()
{ {
if (PreferenceManager.GetDefaultSharedPreferences(Application.Context) if (PreferenceManager.GetDefaultSharedPreferences(LocaleManager.LocalizedAppContext)
.GetBoolean( .GetBoolean(
Application.Context.GetString(Resource.String.LockWhenScreenOff_key), LocaleManager.LocalizedAppContext.GetString(Resource.String.LockWhenScreenOff_key),
false)) false))
{ {
App.Kp2a.Lock(); App.Kp2a.Lock();
@@ -1172,7 +1175,13 @@ namespace keepass2android
#endif #endif
public class App : Application { public class App : Application {
public const string NotificationChannelIdUnlocked = "channel_db_unlocked_5"; public override void OnConfigurationChanged(Android.Content.Res.Configuration newConfig)
{
base.OnConfigurationChanged(newConfig);
LocaleManager.setLocale(this);
}
public const string NotificationChannelIdUnlocked = "channel_db_unlocked_5";
public const string NotificationChannelIdQuicklocked = "channel_db_quicklocked_5"; public const string NotificationChannelIdQuicklocked = "channel_db_quicklocked_5";
public const string NotificationChannelIdEntry = "channel_db_entry_5"; public const string NotificationChannelIdEntry = "channel_db_entry_5";

View File

@@ -549,7 +549,7 @@ namespace keepass2android
{ {
Context ctx = activity; Context ctx = activity;
if (ctx == null) if (ctx == null)
ctx = Application.Context; ctx = LocaleManager.LocalizedAppContext;
if ((ShowUserNotifications == ShowUserNotificationsMode.Always) if ((ShowUserNotifications == ShowUserNotificationsMode.Always)
|| ((ShowUserNotifications == ShowUserNotificationsMode.WhenTotp) && new Kp2aTotp().TryGetAdapter(new PwEntryOutput(activity.Entry, App.Kp2a.CurrentDb)) != null)) || ((ShowUserNotifications == ShowUserNotificationsMode.WhenTotp) && new Kp2aTotp().TryGetAdapter(new PwEntryOutput(activity.Entry, App.Kp2a.CurrentDb)) != null))

View File

@@ -26,8 +26,8 @@ namespace keepass2android
public void UpdatedCachedFileOnLoad(IOConnectionInfo ioc) public void UpdatedCachedFileOnLoad(IOConnectionInfo ioc)
{ {
_app.ShowToast(Application.Context.GetString(Resource.String.UpdatedCachedFileOnLoad, _app.ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.UpdatedCachedFileOnLoad,
new Java.Lang.Object[] { Application.Context.GetString(Resource.String.otp_aux_file) })); new Java.Lang.Object[] { LocaleManager.LocalizedAppContext.GetString(Resource.String.otp_aux_file) }));
} }
public void UpdatedRemoteFileOnLoad(IOConnectionInfo ioc) public void UpdatedRemoteFileOnLoad(IOConnectionInfo ioc)
@@ -48,12 +48,12 @@ namespace keepass2android
public void ResolvedCacheConflictByUsingRemote(IOConnectionInfo ioc) public void ResolvedCacheConflictByUsingRemote(IOConnectionInfo ioc)
{ {
_app.ShowToast(Application.Context.GetString(Resource.String.ResolvedCacheConflictByUsingRemoteOtpAux)); _app.ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.ResolvedCacheConflictByUsingRemoteOtpAux));
} }
public void ResolvedCacheConflictByUsingLocal(IOConnectionInfo ioc) public void ResolvedCacheConflictByUsingLocal(IOConnectionInfo ioc)
{ {
_app.ShowToast(Application.Context.GetString(Resource.String.ResolvedCacheConflictByUsingLocalOtpAux)); _app.ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.ResolvedCacheConflictByUsingLocalOtpAux));
} }
} }
} }

View File

@@ -75,8 +75,8 @@ private static Drawable _blank;
{ {
get get
{ {
var context = Application.Context; var context = LocaleManager.LocalizedAppContext;
string packageName = PreferenceManager.GetDefaultSharedPreferences(Application.Context).GetString("IconSetKey", context.PackageName); string packageName = PreferenceManager.GetDefaultSharedPreferences(LocaleManager.LocalizedAppContext).GetString("IconSetKey", context.PackageName);
//assume that at the momemt only the built in icons are white //assume that at the momemt only the built in icons are white
return packageName == context.PackageName; return packageName == context.PackageName;
} }
@@ -99,7 +99,7 @@ private static Drawable _blank;
Drawable draw; Drawable draw;
if (!_standardIconMap.TryGetValue(dictKey, out draw)) if (!_standardIconMap.TryGetValue(dictKey, out draw))
{ {
string packageName = PreferenceManager.GetDefaultSharedPreferences(Application.Context).GetString("IconSetKey", context.PackageName); string packageName = PreferenceManager.GetDefaultSharedPreferences(LocaleManager.LocalizedAppContext).GetString("IconSetKey", context.PackageName);
Resources res; Resources res;
try try
@@ -111,7 +111,7 @@ private static Drawable _blank;
//can happen after uninstalling icons //can happen after uninstalling icons
packageName = context.PackageName; packageName = context.PackageName;
res = context.PackageManager.GetResourcesForApplication(packageName); res = context.PackageManager.GetResourcesForApplication(packageName);
PreferenceManager.GetDefaultSharedPreferences(Application.Context) PreferenceManager.GetDefaultSharedPreferences(LocaleManager.LocalizedAppContext)
.Edit() .Edit()
.PutString("IconSetKey", packageName) .PutString("IconSetKey", packageName)
.Commit(); .Commit();

View File

@@ -137,7 +137,7 @@ namespace keepass2android.search
Database database = databases[databaseIndex]; Database database = databases[databaseIndex];
var iconDrawable = database.DrawableFactory.GetIconDrawable(App.Context, database.KpDatabase, iconId, customIconUuid, false) as BitmapDrawable; var iconDrawable = database.DrawableFactory.GetIconDrawable(LocaleManager.LocalizedAppContext, database.KpDatabase, iconId, customIconUuid, false) as BitmapDrawable;
if (iconDrawable?.Bitmap != null) if (iconDrawable?.Bitmap != null)
{ {
@@ -152,7 +152,7 @@ namespace keepass2android.search
copiedCanvas.DrawBitmap(original, 0f, 0f, null); copiedCanvas.DrawBitmap(original, 0f, 0f, null);
var bitmap = copy; var bitmap = copy;
float maxSize = convertDpToPixel(60, App.Context); float maxSize = convertDpToPixel(60, LocaleManager.LocalizedAppContext);
float scale = Math.Min(maxSize / bitmap.Width, maxSize / bitmap.Height); float scale = Math.Min(maxSize / bitmap.Width, maxSize / bitmap.Height);
var scaleWidth = (int)(bitmap.Width * scale); var scaleWidth = (int)(bitmap.Width * scale);
var scaleHeight = (int)(bitmap.Height * scale); var scaleHeight = (int)(bitmap.Height * scale);
@@ -366,7 +366,7 @@ namespace keepass2android.search
value = value.Replace("\r", ""); value = value.Replace("\r", "");
if (intlResourceId > 0) if (intlResourceId > 0)
{ {
return Application.Context.GetString(intlResourceId) + ": "+value; return LocaleManager.LocalizedAppContext.GetString(intlResourceId) + ": "+value;
} }
return context.Key + ": " + value; return context.Key + ": " + value;
} }

View File

@@ -39,6 +39,11 @@ namespace keepass2android.services.AutofillBase
public abstract class AutofillServiceBase: AutofillService public abstract class AutofillServiceBase: AutofillService
{ {
protected override void AttachBaseContext(Context baseContext)
{
base.AttachBaseContext(LocaleManager.setLocale(baseContext));
}
//use a lock to avoid returning a response several times in buggy Firefox during one connection: this avoids flickering //use a lock to avoid returning a response several times in buggy Firefox during one connection: this avoids flickering
//and disappearing of the autofill prompt. //and disappearing of the autofill prompt.
//Instead of using a boolean lock, we use a "time-out lock" which is cleared after a few seconds //Instead of using a boolean lock, we use a "time-out lock" which is cleared after a few seconds

View File

@@ -49,6 +49,11 @@ namespace keepass2android
[Service] [Service]
public class CopyToClipboardService : Service public class CopyToClipboardService : Service
{ {
protected override void AttachBaseContext(Context baseContext)
{
base.AttachBaseContext(LocaleManager.setLocale(baseContext));
}
class PasswordAccessNotificationBuilder class PasswordAccessNotificationBuilder
{ {
private readonly Context _ctx; private readonly Context _ctx;

View File

@@ -136,15 +136,15 @@ namespace keepass2android.services.Kp2aAutofill
{PwDefs.PasswordField, new List<string>{View.AutofillHintPassword}}, {PwDefs.PasswordField, new List<string>{View.AutofillHintPassword}},
{PwDefs.UrlField, new List<string>{W3cHints.URL}}, {PwDefs.UrlField, new List<string>{W3cHints.URL}},
{ {
Application.Context.GetString(Resource.String.TemplateField_CreditCard_CVV), LocaleManager.LocalizedAppContext.GetString(Resource.String.TemplateField_CreditCard_CVV),
new List<string>{View.AutofillHintCreditCardSecurityCode} new List<string>{View.AutofillHintCreditCardSecurityCode}
}, },
{ {
Application.Context.GetString(Resource.String.TemplateField_CreditCard_Owner), LocaleManager.LocalizedAppContext.GetString(Resource.String.TemplateField_CreditCard_Owner),
new List<string>{W3cHints.CC_NAME} new List<string>{W3cHints.CC_NAME}
}, },
{Application.Context.GetString(Resource.String.TemplateField_Number), new List<string>{View.AutofillHintCreditCardNumber}}, {LocaleManager.LocalizedAppContext.GetString(Resource.String.TemplateField_Number), new List<string>{View.AutofillHintCreditCardNumber}},
{Application.Context.GetString(Resource.String.TemplateField_IdCard_Name), new List<string>{View.AutofillHintName}}, {LocaleManager.LocalizedAppContext.GetString(Resource.String.TemplateField_IdCard_Name), new List<string>{View.AutofillHintName}},
}; };
return result; return result;
} }

View File

@@ -39,6 +39,10 @@ namespace keepass2android
[Service] [Service]
public class OngoingNotificationsService : Service public class OngoingNotificationsService : Service
{ {
protected override void AttachBaseContext(Context baseContext)
{
base.AttachBaseContext(LocaleManager.setLocale(baseContext));
}
private ScreenOffReceiver _screenOffReceiver; private ScreenOffReceiver _screenOffReceiver;
#region Service #region Service

View File

@@ -39,6 +39,7 @@ using keepass2android.Utils;
using KeePassLib; using KeePassLib;
using KeePassLib.Cryptography.KeyDerivation; using KeePassLib.Cryptography.KeyDerivation;
using KeePassLib.Interfaces; using KeePassLib.Interfaces;
using System.Collections.Generic;
namespace keepass2android namespace keepass2android
{ {
@@ -170,10 +171,42 @@ namespace keepass2android
//use system notification channels to control notification visibility //use system notification channels to control notification visibility
unlockedNotificationPref.Parent.RemovePreference(unlockedNotificationPref); unlockedNotificationPref.Parent.RemovePreference(unlockedNotificationPref);
} }
FindPreference(GetString(Resource.String.DebugLog_key)).PreferenceChange += OnDebugLogChanged; FindPreference(GetString(Resource.String.DebugLog_key)).PreferenceChange += OnDebugLogChanged;
FindPreference(GetString(Resource.String.DebugLog_send_key)).PreferenceClick += OnSendDebug; FindPreference(GetString(Resource.String.DebugLog_send_key)).PreferenceClick += OnSendDebug;
HashSet<string> supportedLocales = new HashSet<string>() { "en", "af", "ar", "az", "be", "bg", "ca", "cs", "da", "de", "el", "es", "eu", "fa", "fi", "fr", "gl", "he", "hr", "hu", "id", "in", "it", "iw", "ja", "ko", "ml", "nb", "nl", "nn", "no", "pl", "pt", "ro", "ru", "si", "sk", "sl", "sr", "sv", "tr", "uk", "vi", "zh" };
ListPreference appLanguagePref = (ListPreference)FindPreference(GetString(Resource.String.app_language_pref_key));
var localesByCode = new System.Collections.Generic.Dictionary<string, List<Java.Util.Locale>>();
foreach (var loc in Java.Util.Locale.GetAvailableLocales())
{
if (!supportedLocales.Contains(loc.Language))
continue;
if (!localesByCode.ContainsKey(loc.Language))
{
localesByCode[loc.Language] = new List<Java.Util.Locale>();
}
localesByCode[loc.Language].Add(loc);
}
var localesByCodeUnique = localesByCode.Select(l => new KeyValuePair<string, Java.Util.Locale>(l.Key, l.Value.First())).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
List<KeyValuePair<string, List<Java.Util.Locale>>> codesWithMultiple = localesByCode.Where(l => l.Value.Count > 1).ToList();
List<KeyValuePair<string, Java.Util.Locale>> localesByLanguageList = localesByCodeUnique
.OrderBy(kvp => kvp.Value.DisplayLanguage).ToList();
appLanguagePref.SetEntries(localesByLanguageList.Select(kvp => kvp.Value.DisplayLanguage).ToArray());
appLanguagePref.SetEntryValues(localesByLanguageList.Select(kvp => kvp.Value.Language).ToArray());
string languageCode = appLanguagePref.Value;
string summary = GetDisplayLanguage(localesByCodeUnique, languageCode);
((ListPreference)FindPreference(GetString(Resource.String.app_language_pref_key))).Summary = summary;
appLanguagePref.PreferenceChange += (sender, args) =>
{
((ListPreference)FindPreference(GetString(Resource.String.app_language_pref_key))).Summary = GetDisplayLanguage(localesByCodeUnique, (string)args.NewValue);
LocaleManager.Language = (string)args.NewValue;
};
UpdateAutofillPref(); UpdateAutofillPref();
@@ -184,7 +217,7 @@ namespace keepass2android
{ {
var intent = new Intent(Settings.ActionRequestSetAutofillService); var intent = new Intent(Settings.ActionRequestSetAutofillService);
if (((AutofillManager) Activity.GetSystemService(Java.Lang.Class.FromType(typeof(AutofillManager)))) if (((AutofillManager)Activity.GetSystemService(Java.Lang.Class.FromType(typeof(AutofillManager))))
.HasEnabledAutofillServices) .HasEnabledAutofillServices)
{ {
intent.SetData(Android.Net.Uri.Parse("package:" + Context.PackageName + "notexisting")); //if we use our package name, the activity won't launch intent.SetData(Android.Net.Uri.Parse("package:" + Context.PackageName + "notexisting")); //if we use our package name, the activity won't launch
@@ -218,45 +251,45 @@ namespace keepass2android
PrepareNoDonatePreference(Activity, FindPreference(GetString(Resource.String.NoDonateOption_key))); PrepareNoDonatePreference(Activity, FindPreference(GetString(Resource.String.NoDonateOption_key)));
PrepareNoDonationReminderPreference(Activity, ((PreferenceScreen)FindPreference(GetString(Resource.String.display_prefs_key))), FindPreference(GetString(Resource.String.NoDonationReminder_key))); PrepareNoDonationReminderPreference(Activity, ((PreferenceScreen)FindPreference(GetString(Resource.String.display_prefs_key))), FindPreference(GetString(Resource.String.NoDonationReminder_key)));
FindPreference(GetString(Resource.String.design_key)).PreferenceChange += (sender, args) => Activity.Recreate();
FindPreference(GetString(Resource.String.design_key)).PreferenceChange += (sender, args) => Activity.Recreate();
Database db = App.Kp2a.CurrentDb; Database db = App.Kp2a.CurrentDb;
if (db != null) if (db != null)
{ {
ListPreference kdfPref = (ListPreference) FindPreference(GetString(Resource.String.kdf_key)); ListPreference kdfPref = (ListPreference)FindPreference(GetString(Resource.String.kdf_key));
kdfPref.SetEntries(KdfPool.Engines.Select(eng => eng.Name).ToArray()); kdfPref.SetEntries(KdfPool.Engines.Select(eng => eng.Name).ToArray());
string[] kdfValues = KdfPool.Engines.Select(eng => eng.Uuid.ToHexString()).ToArray(); string[] kdfValues = KdfPool.Engines.Select(eng => eng.Uuid.ToHexString()).ToArray();
kdfPref.SetEntryValues(kdfValues); kdfPref.SetEntryValues(kdfValues);
kdfPref.SetValueIndex(kdfValues.Select((v, i) => new {kdf = v, index = i}).First(el => el.kdf == db.KpDatabase.KdfParameters.KdfUuid.ToHexString()).index); kdfPref.SetValueIndex(kdfValues.Select((v, i) => new { kdf = v, index = i }).First(el => el.kdf == db.KpDatabase.KdfParameters.KdfUuid.ToHexString()).index);
kdfPref.PreferenceChange += OnKdfChange; kdfPref.PreferenceChange += OnKdfChange;
aesRounds = FindPreference(GetString(Resource.String.rounds_key));
argon2rounds = FindPreference("argon2rounds");
argon2memory = FindPreference("argon2memory");
argon2parallelism = FindPreference("argon2parallelism");
aesRounds.PreferenceChange += (sender, e) => UpdateKdfSummary(e.Preference); aesRounds = FindPreference(GetString(Resource.String.rounds_key));
argon2rounds.PreferenceChange += (sender, e) => UpdateKdfSummary(e.Preference); argon2rounds = FindPreference("argon2rounds");
argon2memory.PreferenceChange += (sender, e) => UpdateKdfSummary(e.Preference); argon2memory = FindPreference("argon2memory");
argon2parallelism.PreferenceChange += (sender, e) => UpdateKdfSummary(e.Preference); argon2parallelism = FindPreference("argon2parallelism");
aesRounds.PreferenceChange += (sender, e) => UpdateKdfSummary(e.Preference);
argon2rounds.PreferenceChange += (sender, e) => UpdateKdfSummary(e.Preference);
argon2memory.PreferenceChange += (sender, e) => UpdateKdfSummary(e.Preference);
argon2parallelism.PreferenceChange += (sender, e) => UpdateKdfSummary(e.Preference);
UpdateKdfScreen();
UpdateKdfScreen();
PrepareDefaultUsername(db); PrepareDefaultUsername(db);
PrepareDatabaseName(db); PrepareDatabaseName(db);
PrepareMasterPassword(); PrepareMasterPassword();
PrepareTemplates(db); PrepareTemplates(db);
ListPreference algorithmPref = (ListPreference)FindPreference(GetString(Resource.String.algorithm_key)); ListPreference algorithmPref = (ListPreference)FindPreference(GetString(Resource.String.algorithm_key));
algorithmPref.SetEntries(CipherPool.GlobalPool.Engines.Select(eng => eng.DisplayName).ToArray()); algorithmPref.SetEntries(CipherPool.GlobalPool.Engines.Select(eng => eng.DisplayName).ToArray());
string[] algoValues = CipherPool.GlobalPool.Engines.Select(eng => eng.CipherUuid.ToHexString()).ToArray(); string[] algoValues = CipherPool.GlobalPool.Engines.Select(eng => eng.CipherUuid.ToHexString()).ToArray();
algorithmPref.SetEntryValues(algoValues); algorithmPref.SetEntryValues(algoValues);
algorithmPref.SetValueIndex(algoValues.Select((v, i) => new { kdf = v, index = i }).First(el => el.kdf == db.KpDatabase.DataCipherUuid.ToHexString()).index); algorithmPref.SetValueIndex(algoValues.Select((v, i) => new { kdf = v, index = i }).First(el => el.kdf == db.KpDatabase.DataCipherUuid.ToHexString()).index);
algorithmPref.PreferenceChange += AlgorithmPrefChange; algorithmPref.PreferenceChange += AlgorithmPrefChange;
algorithmPref.Summary = algorithmPref.Summary =
CipherPool.GlobalPool.GetCipher(App.Kp2a.CurrentDb.KpDatabase.DataCipherUuid).DisplayName; CipherPool.GlobalPool.GetCipher(App.Kp2a.CurrentDb.KpDatabase.DataCipherUuid).DisplayName;
UpdateImportDbPref(); UpdateImportDbPref();
UpdateImportKeyfilePref(); UpdateImportKeyfilePref();
} }
@@ -292,26 +325,36 @@ namespace keepass2android
} }
catch (Exception ex) catch (Exception ex)
{ {
Kp2aLog.LogUnexpectedError(ex); Kp2aLog.LogUnexpectedError(ex);
} }
//AppSettingsActivity.PrepareKeyboardSwitchingPreferences(this); //AppSettingsActivity.PrepareKeyboardSwitchingPreferences(this);
_switchPrefManager = new KeyboardSwitchPrefManager(this); _switchPrefManager = new KeyboardSwitchPrefManager(this);
PrepareSeparateNotificationsPreference(); PrepareSeparateNotificationsPreference();
FindPreference("IconSetKey").PreferenceChange += (sender, args) => FindPreference("IconSetKey").PreferenceChange += (sender, args) =>
{ {
if (App.Kp2a.CurrentDb!= null) if (App.Kp2a.CurrentDb != null)
App.Kp2a.CurrentDb.DrawableFactory.Clear(); App.Kp2a.CurrentDb.DrawableFactory.Clear();
}; };
Preference cachingPreference = FindPreference(GetString(Resource.String.UseOfflineCache_key)); Preference cachingPreference = FindPreference(GetString(Resource.String.UseOfflineCache_key));
cachingPreference.PreferenceChange += OnUseOfflineCacheChanged; cachingPreference.PreferenceChange += OnUseOfflineCacheChanged;
}
private string GetDisplayLanguage(Dictionary<string, Java.Util.Locale> localesByCode, string languageCode)
{
return languageCode != null && localesByCode.ContainsKey(languageCode) ? localesByCode[languageCode]?.DisplayLanguage : GetString(Resource.String.SystemLanguage);
}
private void AppLanguagePref_PreferenceChange(object sender, Preference.PreferenceChangeEventArgs e)
{
throw new NotImplementedException();
} }
private void UpdateAutofillPref() private void UpdateAutofillPref()
@@ -625,7 +668,7 @@ namespace keepass2android
catch (Exception ex) catch (Exception ex)
{ {
Kp2aLog.LogUnexpectedError(ex); Kp2aLog.LogUnexpectedError(ex);
Toast.MakeText(Application.Context, ex.Message, ToastLength.Long).Show(); Toast.MakeText(LocaleManager.LocalizedAppContext, ex.Message, ToastLength.Long).Show();
} }
} }
); );

View File

@@ -67,7 +67,7 @@ namespace keepass2android
AlarmManager am = (AlarmManager)ctx.GetSystemService(Context.AlarmService); AlarmManager am = (AlarmManager)ctx.GetSystemService(Context.AlarmService);
Kp2aLog.Log("Timeout start"); Kp2aLog.Log("Timeout start");
am.Set(AlarmType.Rtc, triggerTime, BuildPendingBroadcastIntent(App.Context)); am.Set(AlarmType.Rtc, triggerTime, BuildPendingBroadcastIntent(LocaleManager.LocalizedAppContext));
} }
public static void ResumingApp(Context ctx) public static void ResumingApp(Context ctx)
@@ -77,7 +77,7 @@ namespace keepass2android
AlarmManager am = (AlarmManager)ctx.GetSystemService(Context.AlarmService); AlarmManager am = (AlarmManager)ctx.GetSystemService(Context.AlarmService);
//cancel alarm //cancel alarm
Kp2aLog.Log("Timeout cancel"); Kp2aLog.Log("Timeout cancel");
am.Cancel(BuildPendingBroadcastIntent(App.Context)); am.Cancel(BuildPendingBroadcastIntent(LocaleManager.LocalizedAppContext));
App.Kp2a.TimeoutTime = DateTime.MaxValue; App.Kp2a.TimeoutTime = DateTime.MaxValue;
} }