Merge branch 'master' of c:/ph/keepass2android
This commit is contained in:
@@ -216,7 +216,7 @@ namespace keepass2android
|
||||
{
|
||||
_cancellationSignal.Cancel();
|
||||
}
|
||||
catch (System.ObjectDisposedException e)
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Kp2aLog.LogUnexpectedError(e);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/image_list_view_row_table_layout"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:paddingLeft="6dip"
|
||||
android:paddingRight="?android:attr/scrollbarSize" >
|
||||
<TextView
|
||||
android:id="@+id/disabled_query_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingRight="40dip"
|
||||
android:singleLine="true"
|
||||
android:textColor="@android:color/black"
|
||||
/>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/disabled_query_checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:checked="false"
|
||||
android:gravity="right" />
|
||||
</RelativeLayout>
|
||||
@@ -90,6 +90,9 @@
|
||||
<string name="DebugLog_key">DebugLog_key</string>
|
||||
<string name="DebugLog_prefs_key">DebugLog_prefs_key</string>
|
||||
<string name="DebugLog_send_key">DebugLog_send</string>
|
||||
<string name="AutofillDisabledQueriesPreference_key">AutofillDisabledQueriesPreference_key</string>
|
||||
<string name="OfferSaveCredentials_key">OfferSaveCredentials_key</string>
|
||||
<string name="AutoFill_prefs_screen_key">AutoFill_prefs_screen_key</string>
|
||||
|
||||
<string name="password_access_prefs_key">password_access_prefs_key</string>
|
||||
<string name="security_prefs_key">security_prefs_key</string>
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
<string name="ShowGroupnameInSearchResult_title">Display group name in search result</string>
|
||||
<string name="ShowGroupnameInSearchResult_resume">Display group name below entry titles in search results. Useful if several entries have the same name.</string>
|
||||
<string name="NavigationToGroupCompleted_message">Display group is now: %1$s</string>
|
||||
<string name="AutofillDisabledQueriesPreference_title">Disabled AutoFill targets</string>
|
||||
<string name="AutofillDisabledQueriesPreference_summary">Views a list of apps and websites for which AutoFill has been disabled</string>
|
||||
<string name="OfferSaveCredentials_summary">If enabled, Android will ask if you want to save credentials after you manually entered data into auto-fillable fields.</string>
|
||||
<string name="OfferSaveCredentials_title">Offer saving of credentials</string>
|
||||
|
||||
<string name="ShowGroupInEntry_title">Show group name in entry view</string>
|
||||
|
||||
|
||||
@@ -403,11 +403,35 @@
|
||||
android:data="https://philippc.github.io/keepass2android/AccServiceAutoFill.html" />
|
||||
</Preference>
|
||||
|
||||
<PreferenceScreen
|
||||
android:key="@string/AutoFill_prefs_screen_key"
|
||||
android:title="@string/AutoFill_prefs"
|
||||
>
|
||||
<keepass2android.ToolbarPreference
|
||||
android:key="@string/AutoFill_prefs_screen_key"
|
||||
android:title="@string/AutoFill_prefs" />
|
||||
<Preference
|
||||
android:key="@string/AutoFill_prefs_key"
|
||||
android:title="@string/AutoFill_prefs">
|
||||
|
||||
</Preference>
|
||||
|
||||
|
||||
<CheckBoxPreference
|
||||
android:enabled="true"
|
||||
android:persistent="true"
|
||||
android:summary="@string/OfferSaveCredentials_summary"
|
||||
android:defaultValue="true"
|
||||
android:title="@string/OfferSaveCredentials_title"
|
||||
android:key="@string/OfferSaveCredentials_key" />
|
||||
|
||||
<keepass2android.AutofillDisabledQueriesPreference
|
||||
android:title="@string/AutofillDisabledQueriesPreference_title"
|
||||
android:summary="@string/AutofillDisabledQueriesPreference_summary"
|
||||
android:persistent="false"
|
||||
android:key="AutofillDisabledQueriesPreference_key"/>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
<CheckBoxPreference
|
||||
android:enabled="true"
|
||||
|
||||
@@ -23,6 +23,7 @@ using keepass2android.Utils;
|
||||
using KeePassLib;
|
||||
using KeePassLib.Keys;
|
||||
using KeePassLib.Serialization;
|
||||
using Console = System.Console;
|
||||
using Object = Java.Lang.Object;
|
||||
|
||||
namespace keepass2android
|
||||
@@ -317,7 +318,16 @@ namespace keepass2android
|
||||
|
||||
foreach (var db in App.Kp2a.OpenDatabases)
|
||||
{
|
||||
if (OpenAutoExecEntries(db)) return;
|
||||
try
|
||||
{
|
||||
if (OpenAutoExecEntries(db)) return;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Toast.MakeText(this, "Failed to open child databases",ToastLength.Long).Show();
|
||||
Kp2aLog.LogUnexpectedError(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//database(s) unlocked
|
||||
@@ -341,26 +351,34 @@ namespace keepass2android
|
||||
|
||||
private bool OpenAutoExecEntries(Database db)
|
||||
{
|
||||
string thisDevice = KeeAutoExecExt.ThisDeviceId;
|
||||
foreach (var autoOpenItem in KeeAutoExecExt.GetAutoExecItems(db.KpDatabase))
|
||||
try
|
||||
{
|
||||
if (!autoOpenItem.Enabled)
|
||||
continue;
|
||||
if (!KeeAutoExecExt.IsDeviceEnabled(autoOpenItem, thisDevice, out _))
|
||||
continue;
|
||||
IOConnectionInfo dbIoc;
|
||||
if (KeeAutoExecExt.TryGetDatabaseIoc(autoOpenItem, out dbIoc) &&
|
||||
App.Kp2a.TryGetDatabase(dbIoc) == null &&
|
||||
App.Kp2a.AttemptedToOpenBefore(dbIoc) == false
|
||||
)
|
||||
string thisDevice = KeeAutoExecExt.ThisDeviceId;
|
||||
foreach (var autoOpenItem in KeeAutoExecExt.GetAutoExecItems(db.KpDatabase))
|
||||
{
|
||||
if (KeeAutoExecExt.AutoOpenEntry(this, autoOpenItem, false))
|
||||
if (!autoOpenItem.Enabled)
|
||||
continue;
|
||||
if (!KeeAutoExecExt.IsDeviceEnabled(autoOpenItem, thisDevice, out _))
|
||||
continue;
|
||||
IOConnectionInfo dbIoc;
|
||||
if (KeeAutoExecExt.TryGetDatabaseIoc(autoOpenItem, out dbIoc) &&
|
||||
App.Kp2a.TryGetDatabase(dbIoc) == null &&
|
||||
App.Kp2a.AttemptedToOpenBefore(dbIoc) == false
|
||||
)
|
||||
{
|
||||
LaunchingOther = true;
|
||||
return true;
|
||||
if (KeeAutoExecExt.AutoOpenEntry(this, autoOpenItem, false))
|
||||
{
|
||||
LaunchingOther = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Kp2aLog.LogUnexpectedError(e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -449,12 +449,7 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
public void LockSingleDatabase(Database databaseToLock, bool allowQuickUnlock)
|
||||
{
|
||||
//TODO implement
|
||||
throw new Exception("lock single is not implemented");
|
||||
}
|
||||
|
||||
|
||||
private void AskForReload(Activity activity)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
|
||||
@@ -260,9 +260,11 @@
|
||||
<Compile Include="services\Kp2aAutofill\Kp2aAutofillService.cs" />
|
||||
<Compile Include="services\OngoingNotificationsService.cs" />
|
||||
<Compile Include="settings\Argon2Preference.cs" />
|
||||
<Compile Include="settings\AutofillDisabledQueriesPreference.cs" />
|
||||
<Compile Include="settings\DatabaseSettingsActivity.cs" />
|
||||
<Compile Include="intents\Intents.cs" />
|
||||
<Compile Include="SelectCurrentDbActivity.cs" />
|
||||
<Compile Include="settings\IconSetPreference.cs" />
|
||||
<Compile Include="SwitchImeActivity.cs" />
|
||||
<Compile Include="timeout\TimeoutHelper.cs" />
|
||||
<Compile Include="GroupActivity.cs" />
|
||||
@@ -379,6 +381,9 @@
|
||||
<AndroidResource Include="Resources\layout\httpcredentials.axml">
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
<AndroidResource Include="Resources\layout\disabled_queries_preference_row.axml">
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
<None Include="settings\RoundsPreference %28Kopie%29.cs">
|
||||
<Visible>False</Visible>
|
||||
</None>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Android.Content;
|
||||
using Android.Content.PM;
|
||||
using Android.OS;
|
||||
using Android.Preferences;
|
||||
using Android.Runtime;
|
||||
@@ -80,8 +81,9 @@ namespace keepass2android.services.AutofillBase
|
||||
|
||||
AddQueryDataset(query, isManual, autofillIds, responseBuilder, !hasEntryDataset);
|
||||
AddDisableDataset(query, autofillIds, responseBuilder, isManual);
|
||||
responseBuilder.SetSaveInfo(new SaveInfo.Builder(parser.AutofillFields.SaveType,
|
||||
parser.AutofillFields.GetAutofillIds()).Build());
|
||||
if (PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean(GetString(Resource.String.OfferSaveCredentials_key), true))
|
||||
responseBuilder.SetSaveInfo(new SaveInfo.Builder(parser.AutofillFields.SaveType,
|
||||
parser.AutofillFields.GetAutofillIds()).Build());
|
||||
|
||||
callback.OnSuccess(responseBuilder.Build());
|
||||
}
|
||||
@@ -120,7 +122,35 @@ namespace keepass2android.services.AutofillBase
|
||||
|
||||
responseBuilder.AddDataset(datasetBuilder.Build());
|
||||
}
|
||||
|
||||
public static string GetDisplayNameForQuery(string str, Context Context)
|
||||
{
|
||||
string displayName = str;
|
||||
try
|
||||
{
|
||||
string appPrefix = "androidapp://";
|
||||
if (str.StartsWith(appPrefix))
|
||||
{
|
||||
str = str.Substring(appPrefix.Length);
|
||||
PackageManager pm = Context.PackageManager;
|
||||
ApplicationInfo ai;
|
||||
try
|
||||
{
|
||||
ai = pm.GetApplicationInfo(str, 0);
|
||||
}
|
||||
catch (PackageManager.NameNotFoundException e)
|
||||
{
|
||||
ai = null;
|
||||
}
|
||||
displayName = ai != null ? pm.GetApplicationLabel(ai) : str;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Kp2aLog.LogUnexpectedError(e);
|
||||
}
|
||||
|
||||
return displayName;
|
||||
}
|
||||
|
||||
private void AddDisableDataset(string query, AutofillId[] autofillIds, FillResponse.Builder responseBuilder, bool isManual)
|
||||
{
|
||||
@@ -131,7 +161,7 @@ namespace keepass2android.services.AutofillBase
|
||||
var sender = IntentBuilder.GetDisableIntentSenderForResponse(this, query, isManual, isForDisable);
|
||||
|
||||
RemoteViews presentation = AutofillHelper.NewRemoteViews(PackageName,
|
||||
GetString(isForDisable ? Resource.String.autofill_disable : Resource.String.autofill_enable_for, new Java.Lang.Object[] { query}), Resource.Drawable.ic_menu_close_grey);
|
||||
GetString(isForDisable ? Resource.String.autofill_disable : Resource.String.autofill_enable_for, new Java.Lang.Object[] { GetDisplayNameForQuery(query, this)}), Resource.Drawable.ic_menu_close_grey);
|
||||
|
||||
var datasetBuilder = new Dataset.Builder(presentation);
|
||||
datasetBuilder.SetAuthentication(sender);
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Content.PM;
|
||||
using Android.Content.Res;
|
||||
using Android.Preferences;
|
||||
using Android.Runtime;
|
||||
using Android.Util;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using keepass2android.services.AutofillBase;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
public class AutofillDisabledQueriesPreference : ListPreference
|
||||
{
|
||||
|
||||
|
||||
private class DisabledQuery
|
||||
{
|
||||
public string Query { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
}
|
||||
|
||||
private class DisabledQueryPreferenceScreenAdapter : BaseAdapter
|
||||
{
|
||||
public Dictionary<string, bool> DisabledQueriesValues = new Dictionary<string, bool>();
|
||||
|
||||
private readonly AutofillDisabledQueriesPreference _pref;
|
||||
|
||||
public DisabledQueryPreferenceScreenAdapter(AutofillDisabledQueriesPreference pref, Context context)
|
||||
{
|
||||
_pref = pref;
|
||||
}
|
||||
|
||||
|
||||
private class CustomHolder : Java.Lang.Object
|
||||
{
|
||||
private TextView text = null;
|
||||
private CheckBox checkbox = null;
|
||||
|
||||
public CustomHolder(View row, int position, AutofillDisabledQueriesPreference pref)
|
||||
{
|
||||
text = (TextView) row.FindViewById(Resource.Id.disabled_query_text);
|
||||
text.Text = pref.DisabledQueries[position].DisplayName;
|
||||
|
||||
checkbox = (CheckBox) row.FindViewById(Resource.Id.disabled_query_checkbox);
|
||||
checkbox.Id = position;
|
||||
checkbox.Clickable = true;
|
||||
checkbox.Checked = true;
|
||||
|
||||
}
|
||||
|
||||
public CheckBox Checkbox
|
||||
{
|
||||
get { return checkbox; }
|
||||
}
|
||||
}
|
||||
|
||||
public override Java.Lang.Object GetItem(int position)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override long GetItemId(int position)
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override View GetView(int position, View convertView, ViewGroup parent)
|
||||
{
|
||||
View row = convertView;
|
||||
CustomHolder holder = null;
|
||||
int p = position;
|
||||
row = LayoutInflater.From(_pref.Context)
|
||||
.Inflate(Resource.Layout.disabled_queries_preference_row, parent, false);
|
||||
holder = new CustomHolder(row, position, _pref);
|
||||
|
||||
row.Tag = holder;
|
||||
|
||||
/*row.Clickable = true;
|
||||
row.Focusable = true;
|
||||
row.FocusableInTouchMode = true;
|
||||
*/
|
||||
((CustomHolder) row.Tag).Checkbox.CheckedChange += (sender, args) =>
|
||||
{
|
||||
DisabledQueriesValues[_pref.DisabledQueries[p].Query] = args.IsChecked;
|
||||
};
|
||||
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
public override int Count
|
||||
{
|
||||
get { return _pref.DisabledQueries.Count; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
List<DisabledQuery> _disabledQueries = null;
|
||||
|
||||
private List<DisabledQuery> DisabledQueries
|
||||
{
|
||||
get
|
||||
{
|
||||
var prefs = PreferenceManager.GetDefaultSharedPreferences(this.Context);
|
||||
_disabledQueries = prefs.GetStringSet("AutoFillDisabledQueries", new List<string>()).Select(str =>
|
||||
new DisabledQuery() {Query = str, DisplayName = AutofillServiceBase.GetDisplayNameForQuery(str, Context)}).ToList();
|
||||
|
||||
return _disabledQueries;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected AutofillDisabledQueriesPreference(IntPtr javaReference, JniHandleOwnership transfer)
|
||||
: base(javaReference, transfer)
|
||||
{
|
||||
}
|
||||
|
||||
private readonly Task _populatorTask;
|
||||
|
||||
public AutofillDisabledQueriesPreference(Context context, IAttributeSet attrs)
|
||||
: base(context, attrs)
|
||||
{
|
||||
_populatorTask = Task.Factory.StartNew(() =>
|
||||
{
|
||||
SetEntries(DisabledQueries.Select(s => s.DisplayName).ToArray());
|
||||
SetEntryValues(DisabledQueries.Select(s => s.Query).ToArray());
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected override void OnPrepareDialogBuilder(AlertDialog.Builder builder)
|
||||
{
|
||||
_populatorTask.Wait();
|
||||
base.OnPrepareDialogBuilder(builder);
|
||||
|
||||
|
||||
var adapter = new DisabledQueryPreferenceScreenAdapter(this, Context);
|
||||
|
||||
builder.SetAdapter(adapter, (sender, args) => { });
|
||||
builder.SetPositiveButton(Android.Resource.String.Ok, (sender, args) =>
|
||||
{
|
||||
List<string> newList = adapter.DisabledQueriesValues.Where(kvp => kvp.Value).Select(kvp => kvp.Key).ToList();
|
||||
var prefs = PreferenceManager.GetDefaultSharedPreferences(this.Context);
|
||||
prefs.Edit().PutStringSet("AutoFillDisabledQueries", newList).Commit();
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,24 +16,16 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Content.PM;
|
||||
using Android.Content.Res;
|
||||
using Android.Graphics;
|
||||
using Android.Graphics.Drawables;
|
||||
using Android.OS;
|
||||
using Android.Widget;
|
||||
using Android.Preferences;
|
||||
using Android.Provider;
|
||||
using Android.Runtime;
|
||||
using Android.Util;
|
||||
using Android.Views;
|
||||
using Android.Views.Autofill;
|
||||
using Java.IO;
|
||||
using KeePassLib.Cryptography.Cipher;
|
||||
@@ -47,203 +39,6 @@ using KeePassLib.Cryptography.KeyDerivation;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
|
||||
public class IconSetPreference : ListPreference
|
||||
{
|
||||
private int selectedEntry;
|
||||
|
||||
private class IconSet
|
||||
{
|
||||
public string PackageName { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public Drawable GetIcon(Context context)
|
||||
{
|
||||
if (PackageName == context.PackageName)
|
||||
return context.Resources.GetDrawable(Resource.Drawable.ic00);
|
||||
Resources res = context.PackageManager.GetResourcesForApplication(PackageName);
|
||||
|
||||
return res.GetDrawable(res.GetIdentifier("ic00", "drawable", PackageName));
|
||||
}
|
||||
}
|
||||
|
||||
private class IconListPreferenceScreenAdapter : BaseAdapter
|
||||
{
|
||||
private readonly IconSetPreference _pref;
|
||||
|
||||
public IconListPreferenceScreenAdapter(IconSetPreference pref, Context context)
|
||||
{
|
||||
_pref = pref;
|
||||
}
|
||||
|
||||
|
||||
private class CustomHolder : Java.Lang.Object
|
||||
{
|
||||
private TextView text = null;
|
||||
private RadioButton rButton = null;
|
||||
|
||||
public CustomHolder(View row, int position, IconSetPreference pref)
|
||||
{
|
||||
text = (TextView)row.FindViewById(Resource.Id.image_list_view_row_text_view);
|
||||
text.Text = pref.IconSets[position].DisplayName;
|
||||
|
||||
rButton = (RadioButton)row.FindViewById(Resource.Id.image_list_view_row_radio_button);
|
||||
rButton.Id = position;
|
||||
rButton.Clickable = false;
|
||||
rButton.Checked = (pref.selectedEntry == position);
|
||||
|
||||
try
|
||||
{
|
||||
Drawable dr = pref.IconSets[position].GetIcon(row.Context);
|
||||
var bitmap = ((BitmapDrawable)dr).Bitmap;
|
||||
Drawable d = new BitmapDrawable(row.Resources, Bitmap.CreateScaledBitmap(bitmap, 64, 64, true));
|
||||
text.SetCompoundDrawablesWithIntrinsicBounds(d, null, null, null);
|
||||
text.Text = (" " + text.Text);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public override Java.Lang.Object GetItem(int position)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override long GetItemId(int position)
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override View GetView(int position, View convertView, ViewGroup parent)
|
||||
{
|
||||
View row = convertView;
|
||||
CustomHolder holder = null;
|
||||
int p = position;
|
||||
row = LayoutInflater.From(_pref.Context).Inflate(Resource.Layout.image_list_preference_row, parent, false);
|
||||
holder = new CustomHolder(row, position, _pref);
|
||||
|
||||
row.Tag = holder;
|
||||
|
||||
// row.setClickable(true);
|
||||
// row.setFocusable(true);
|
||||
// row.setFocusableInTouchMode(true);
|
||||
row.Click += (sender, args) =>
|
||||
{
|
||||
|
||||
((View)sender).RequestFocus();
|
||||
|
||||
Dialog mDialog = _pref.Dialog;
|
||||
mDialog.Dismiss();
|
||||
|
||||
_pref.CallChangeListener(_pref.IconSets[p].PackageName);
|
||||
ISharedPreferences pref = PreferenceManager.GetDefaultSharedPreferences(_pref.Context);
|
||||
var edit = pref.Edit();
|
||||
edit.PutString(_pref.Key, _pref.IconSets[p].PackageName);
|
||||
edit.Commit();
|
||||
_pref.selectedEntry = p;
|
||||
|
||||
};
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
public override int Count
|
||||
{
|
||||
get { return _pref.IconSets.Count; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
List<IconSet> _iconSets = null;
|
||||
List<IconSet> IconSets
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_iconSets != null)
|
||||
return _iconSets;
|
||||
_iconSets = new List<IconSet>();
|
||||
|
||||
_iconSets.Add(new IconSet()
|
||||
{
|
||||
DisplayName = Context.GetString(AppNames.AppNameResource),
|
||||
PackageName = Context.PackageName
|
||||
});
|
||||
|
||||
foreach (var p in Context.PackageManager.GetInstalledPackages(0))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
string packageName = p.PackageName;
|
||||
Resources res = Context.PackageManager.GetResourcesForApplication(packageName);
|
||||
int nameId = res.GetIdentifier("kp2a_iconset_name", "string", packageName);
|
||||
_iconSets.Add(new IconSet()
|
||||
{
|
||||
DisplayName = res.GetString(nameId),
|
||||
PackageName = packageName
|
||||
});
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
return _iconSets;
|
||||
}
|
||||
}
|
||||
protected IconSetPreference(IntPtr javaReference, JniHandleOwnership transfer)
|
||||
: base(javaReference, transfer)
|
||||
{
|
||||
}
|
||||
|
||||
private readonly Task _populatorTask;
|
||||
|
||||
public IconSetPreference(Context context, IAttributeSet attrs)
|
||||
: base(context, attrs)
|
||||
{
|
||||
_populatorTask = Task.Factory.StartNew(() =>
|
||||
{
|
||||
SetEntries(IconSets.Select(s => s.DisplayName).ToArray());
|
||||
SetEntryValues(IconSets.Select(s => s.PackageName).ToArray());
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected override void OnPrepareDialogBuilder(AlertDialog.Builder builder)
|
||||
{
|
||||
_populatorTask.Wait();
|
||||
base.OnPrepareDialogBuilder(builder);
|
||||
|
||||
|
||||
var iconListPreferenceAdapter = new IconListPreferenceScreenAdapter(this, Context);
|
||||
|
||||
String selectedValue = PreferenceManager.GetDefaultSharedPreferences(Context).GetString(Key, "");
|
||||
for (int i = 0; i < IconSets.Count; i++)
|
||||
{
|
||||
if (selectedValue == IconSets[i].PackageName)
|
||||
{
|
||||
selectedEntry = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
builder.SetAdapter(iconListPreferenceAdapter, (sender, args) => { });
|
||||
builder.SetNeutralButton(Resource.String.IconSet_install, (sender, args) =>
|
||||
{
|
||||
Util.GotoUrl(Context, "market://search?q=keepass2android icon set");
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//http://stackoverflow.com/a/27422401/292233
|
||||
public class SettingsFragment : PreferenceFragment
|
||||
{
|
||||
@@ -406,7 +201,7 @@ namespace keepass2android
|
||||
new AlertDialog.Builder(Context)
|
||||
.SetTitle(Resource.String.autofill_enable)
|
||||
.SetMessage(Resource.String.autofill_enable_failed)
|
||||
.SetPositiveButton(Resource.String.ok, (o, eventArgs) => { })
|
||||
.SetPositiveButton(Android.Resource.String.Ok, (o, eventArgs) => { })
|
||||
.Show();
|
||||
|
||||
}
|
||||
@@ -517,7 +312,10 @@ namespace keepass2android
|
||||
|
||||
private void UpdateAutofillPref()
|
||||
{
|
||||
var autofillScreen = FindPreference(GetString(Resource.String.AutoFill_prefs_screen_key));
|
||||
var autofillPref = FindPreference(GetString(Resource.String.AutoFill_prefs_key));
|
||||
var autofillDisabledPref = FindPreference(GetString(Resource.String.AutofillDisabledQueriesPreference_key));
|
||||
var autofillSavePref = FindPreference(GetString(Resource.String.OfferSaveCredentials_key));
|
||||
if (autofillPref == null)
|
||||
return;
|
||||
if ((Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.O) ||
|
||||
@@ -526,19 +324,23 @@ namespace keepass2android
|
||||
{
|
||||
var passwordAccessScreen =
|
||||
(PreferenceScreen) FindPreference(Activity.GetString(Resource.String.password_access_prefs_key));
|
||||
passwordAccessScreen.RemovePreference(autofillPref);
|
||||
passwordAccessScreen.RemovePreference(autofillScreen);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (((AutofillManager) Activity.GetSystemService(Java.Lang.Class.FromType(typeof(AutofillManager))))
|
||||
.HasEnabledAutofillServices)
|
||||
{
|
||||
autofillDisabledPref.Enabled = true;
|
||||
autofillSavePref.Enabled = true;
|
||||
autofillPref.Summary = Activity.GetString(Resource.String.plugin_enabled);
|
||||
autofillPref.Intent = new Intent(Intent.ActionView);
|
||||
autofillPref.Intent.SetData(Android.Net.Uri.Parse("https://philippc.github.io/keepass2android/OreoAutoFill.html"));
|
||||
}
|
||||
else
|
||||
{
|
||||
autofillDisabledPref.Enabled = false;
|
||||
autofillSavePref.Enabled = false;
|
||||
autofillPref.Summary = Activity.GetString(Resource.String.not_enabled);
|
||||
}
|
||||
|
||||
@@ -790,10 +592,6 @@ namespace keepass2android
|
||||
|
||||
private void OnUseOfflineCacheChanged(object sender, Preference.PreferenceChangeEventArgs e)
|
||||
{
|
||||
//ensure the user gets a matching database
|
||||
if (App.Kp2a.CurrentDb!= null && !App.Kp2a.CurrentDb.Ioc.IsLocalFile())
|
||||
App.Kp2a.LockSingleDatabase(App.Kp2a.CurrentDb, false);
|
||||
|
||||
if (!(bool)e.NewValue)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(Activity);
|
||||
|
||||
213
src/keepass2android/settings/IconSetPreference.cs
Normal file
213
src/keepass2android/settings/IconSetPreference.cs
Normal file
@@ -0,0 +1,213 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Content.Res;
|
||||
using Android.Graphics;
|
||||
using Android.Graphics.Drawables;
|
||||
using Android.Preferences;
|
||||
using Android.Runtime;
|
||||
using Android.Util;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
public class IconSetPreference : ListPreference
|
||||
{
|
||||
private int selectedEntry;
|
||||
|
||||
private class IconSet
|
||||
{
|
||||
public string PackageName { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public Drawable GetIcon(Context context)
|
||||
{
|
||||
if (PackageName == context.PackageName)
|
||||
return context.Resources.GetDrawable(Resource.Drawable.ic00);
|
||||
Resources res = context.PackageManager.GetResourcesForApplication(PackageName);
|
||||
|
||||
return res.GetDrawable(res.GetIdentifier("ic00", "drawable", PackageName));
|
||||
}
|
||||
}
|
||||
|
||||
private class IconListPreferenceScreenAdapter : BaseAdapter
|
||||
{
|
||||
private readonly IconSetPreference _pref;
|
||||
|
||||
public IconListPreferenceScreenAdapter(IconSetPreference pref, Context context)
|
||||
{
|
||||
_pref = pref;
|
||||
}
|
||||
|
||||
|
||||
private class CustomHolder : Java.Lang.Object
|
||||
{
|
||||
private TextView text = null;
|
||||
private RadioButton rButton = null;
|
||||
|
||||
public CustomHolder(View row, int position, IconSetPreference pref)
|
||||
{
|
||||
text = (TextView)row.FindViewById(Resource.Id.image_list_view_row_text_view);
|
||||
text.Text = pref.IconSets[position].DisplayName;
|
||||
|
||||
rButton = (RadioButton)row.FindViewById(Resource.Id.image_list_view_row_radio_button);
|
||||
rButton.Id = position;
|
||||
rButton.Clickable = false;
|
||||
rButton.Checked = (pref.selectedEntry == position);
|
||||
|
||||
try
|
||||
{
|
||||
Drawable dr = pref.IconSets[position].GetIcon(row.Context);
|
||||
var bitmap = ((BitmapDrawable)dr).Bitmap;
|
||||
Drawable d = new BitmapDrawable(row.Resources, Bitmap.CreateScaledBitmap(bitmap, 64, 64, true));
|
||||
text.SetCompoundDrawablesWithIntrinsicBounds(d, null, null, null);
|
||||
text.Text = (" " + text.Text);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public override Java.Lang.Object GetItem(int position)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override long GetItemId(int position)
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override View GetView(int position, View convertView, ViewGroup parent)
|
||||
{
|
||||
View row = convertView;
|
||||
CustomHolder holder = null;
|
||||
int p = position;
|
||||
row = LayoutInflater.From(_pref.Context).Inflate(Resource.Layout.image_list_preference_row, parent, false);
|
||||
holder = new CustomHolder(row, position, _pref);
|
||||
|
||||
row.Tag = holder;
|
||||
|
||||
// row.setClickable(true);
|
||||
// row.setFocusable(true);
|
||||
// row.setFocusableInTouchMode(true);
|
||||
row.Click += (sender, args) =>
|
||||
{
|
||||
|
||||
((View)sender).RequestFocus();
|
||||
|
||||
Dialog mDialog = _pref.Dialog;
|
||||
mDialog.Dismiss();
|
||||
|
||||
_pref.CallChangeListener(_pref.IconSets[p].PackageName);
|
||||
ISharedPreferences pref = PreferenceManager.GetDefaultSharedPreferences(_pref.Context);
|
||||
var edit = pref.Edit();
|
||||
edit.PutString(_pref.Key, _pref.IconSets[p].PackageName);
|
||||
edit.Commit();
|
||||
_pref.selectedEntry = p;
|
||||
|
||||
};
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
public override int Count
|
||||
{
|
||||
get { return _pref.IconSets.Count; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
List<IconSet> _iconSets = null;
|
||||
List<IconSet> IconSets
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_iconSets != null)
|
||||
return _iconSets;
|
||||
_iconSets = new List<IconSet>();
|
||||
|
||||
_iconSets.Add(new IconSet()
|
||||
{
|
||||
DisplayName = Context.GetString(AppNames.AppNameResource),
|
||||
PackageName = Context.PackageName
|
||||
});
|
||||
|
||||
foreach (var p in Context.PackageManager.GetInstalledPackages(0))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
string packageName = p.PackageName;
|
||||
Resources res = Context.PackageManager.GetResourcesForApplication(packageName);
|
||||
int nameId = res.GetIdentifier("kp2a_iconset_name", "string", packageName);
|
||||
_iconSets.Add(new IconSet()
|
||||
{
|
||||
DisplayName = res.GetString(nameId),
|
||||
PackageName = packageName
|
||||
});
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
return _iconSets;
|
||||
}
|
||||
}
|
||||
protected IconSetPreference(IntPtr javaReference, JniHandleOwnership transfer)
|
||||
: base(javaReference, transfer)
|
||||
{
|
||||
}
|
||||
|
||||
private readonly Task _populatorTask;
|
||||
|
||||
public IconSetPreference(Context context, IAttributeSet attrs)
|
||||
: base(context, attrs)
|
||||
{
|
||||
_populatorTask = Task.Factory.StartNew(() =>
|
||||
{
|
||||
SetEntries(IconSets.Select(s => s.DisplayName).ToArray());
|
||||
SetEntryValues(IconSets.Select(s => s.PackageName).ToArray());
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected override void OnPrepareDialogBuilder(AlertDialog.Builder builder)
|
||||
{
|
||||
_populatorTask.Wait();
|
||||
base.OnPrepareDialogBuilder(builder);
|
||||
|
||||
|
||||
var iconListPreferenceAdapter = new IconListPreferenceScreenAdapter(this, Context);
|
||||
|
||||
String selectedValue = PreferenceManager.GetDefaultSharedPreferences(Context).GetString(Key, "");
|
||||
for (int i = 0; i < IconSets.Count; i++)
|
||||
{
|
||||
if (selectedValue == IconSets[i].PackageName)
|
||||
{
|
||||
selectedEntry = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
builder.SetAdapter(iconListPreferenceAdapter, (sender, args) => { });
|
||||
builder.SetNeutralButton(Resource.String.IconSet_install, (sender, args) =>
|
||||
{
|
||||
Util.GotoUrl(Context, "market://search?q=keepass2android icon set");
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user