Merge branch 'master' of c:/ph/keepass2android
This commit is contained in:
@@ -270,7 +270,7 @@ namespace keepass2android.Io
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
else throw new Exception("couldn't move to first result element: " + (cursor == null) + uri.ToString());
|
||||
else return false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -49,6 +49,11 @@ namespace keepass2android
|
||||
get { return _activeActivity; }
|
||||
private set
|
||||
{
|
||||
if (_activeActivity != null && _activeActivity != _previouslyActiveActivity)
|
||||
{
|
||||
_previouslyActiveActivity = _activeActivity;
|
||||
|
||||
}
|
||||
_activeActivity = value;
|
||||
if (_task != null)
|
||||
_task.ActiveActivity = _activeActivity;
|
||||
@@ -60,12 +65,18 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Handler _handler;
|
||||
public Activity PreviouslyActiveActivity
|
||||
{
|
||||
get { return _previouslyActiveActivity; }
|
||||
|
||||
}
|
||||
|
||||
private readonly Handler _handler;
|
||||
private readonly RunnableOnFinish _task;
|
||||
private IProgressDialog _progressDialog;
|
||||
private readonly IKp2aApp _app;
|
||||
private Thread _thread;
|
||||
private Activity _activeActivity;
|
||||
private Activity _activeActivity, _previouslyActiveActivity;
|
||||
private ProgressDialogStatusLogger _progressDialogStatusLogger;
|
||||
|
||||
public ProgressTask(IKp2aApp app, Activity activity, RunnableOnFinish task)
|
||||
|
||||
@@ -88,6 +88,7 @@ namespace keepass2android
|
||||
ReadOnlyReason_ReadOnlyKitKat,
|
||||
ReadOnlyReason_LocalBackup,
|
||||
Ok,
|
||||
cancel
|
||||
cancel,
|
||||
FileNotFound
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,8 +36,11 @@ namespace keepass2android
|
||||
{
|
||||
_actionToPerform = actionToPerform;
|
||||
}
|
||||
|
||||
public override void Run()
|
||||
|
||||
//if set to true, the previously active active will be passed to ActionToPerformOnFinish instead null if no activity is on foreground
|
||||
public bool AllowInactiveActivity { get; set; }
|
||||
|
||||
public override void Run()
|
||||
{
|
||||
if (Message == null)
|
||||
Message = "";
|
||||
@@ -46,7 +49,7 @@ namespace keepass2android
|
||||
Handler.Post(() => {_actionToPerform(Success, Message, ActiveActivity);});
|
||||
}
|
||||
else
|
||||
_actionToPerform(Success, Message, ActiveActivity);
|
||||
_actionToPerform(Success, Message, AllowInactiveActivity ? (ActiveActivity ?? PreviouslyActiveActivity) : ActiveActivity);
|
||||
base.Run();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace keepass2android
|
||||
{
|
||||
if (!(e is InvalidCompositeKeyException))
|
||||
Kp2aLog.LogUnexpectedError(e);
|
||||
Finish(false, _app.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message, false, Exception);
|
||||
Finish(false, _app.GetResourceString(UiStringKey.ErrorOcurred) + " " + (e.Message ?? (e is FileNotFoundException ? _app.GetResourceString(UiStringKey.FileNotFound) : "")), false, Exception);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace keepass2android
|
||||
protected OnFinish BaseOnFinish;
|
||||
protected Handler Handler;
|
||||
private ProgressDialogStatusLogger _statusLogger = new ProgressDialogStatusLogger(); //default: no logging but not null -> can be used whenever desired
|
||||
private Activity _activeActivity;
|
||||
private Activity _activeActivity, _previouslyActiveActivity;
|
||||
|
||||
|
||||
public ProgressDialogStatusLogger StatusLogger
|
||||
@@ -53,7 +53,12 @@ namespace keepass2android
|
||||
get { return _activeActivity; }
|
||||
set
|
||||
{
|
||||
_activeActivity = value;
|
||||
if (_activeActivity != null && _activeActivity != _previouslyActiveActivity)
|
||||
{
|
||||
_previouslyActiveActivity = _activeActivity;
|
||||
|
||||
}
|
||||
_activeActivity = value;
|
||||
if (BaseOnFinish != null)
|
||||
{
|
||||
BaseOnFinish.ActiveActivity = value;
|
||||
@@ -61,8 +66,15 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
public Activity PreviouslyActiveActivity
|
||||
{
|
||||
get { return _previouslyActiveActivity; }
|
||||
|
||||
protected OnFinish(Activity activeActivity, Handler handler)
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected OnFinish(Activity activeActivity, Handler handler)
|
||||
{
|
||||
ActiveActivity = activeActivity;
|
||||
BaseOnFinish = null;
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.content.Intent;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.burgstaller.okhttp.AuthenticationCacheInterceptor;
|
||||
@@ -44,6 +45,7 @@ import keepass2android.javafilestorage.webdav.PropfindXmlParser;
|
||||
import keepass2android.javafilestorage.webdav.WebDavUtil;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Protocol;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
@@ -52,6 +54,7 @@ import okhttp3.internal.tls.OkHostnameVerifier;
|
||||
public class WebDavStorage extends JavaFileStorageBase {
|
||||
|
||||
private final ICertificateErrorHandler mCertificateErrorHandler;
|
||||
private Context appContext;
|
||||
|
||||
public WebDavStorage(ICertificateErrorHandler certificateErrorHandler)
|
||||
{
|
||||
@@ -125,9 +128,13 @@ public class WebDavStorage extends JavaFileStorageBase {
|
||||
}
|
||||
}
|
||||
|
||||
//client to be reused (connection pool/thread pool). We're building a custom client for each ConnectionInfo in getClient for actual usage
|
||||
final OkHttpClient baseClient = new OkHttpClient();
|
||||
|
||||
private OkHttpClient getClient(ConnectionInfo ci) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException {
|
||||
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||
|
||||
OkHttpClient.Builder builder = baseClient.newBuilder();
|
||||
final Map<String, CachingAuthenticator> authCache = new ConcurrentHashMap<>();
|
||||
|
||||
com.burgstaller.okhttp.digest.Credentials credentials = new com.burgstaller.okhttp.digest.Credentials(ci.username, ci.password);
|
||||
@@ -169,6 +176,12 @@ public class WebDavStorage extends JavaFileStorageBase {
|
||||
builder.writeTimeout(25, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
//OkHttp has issues with HTTP/2 (https://github.com/square/okhttp/issues/4964)
|
||||
//An OkHttp developer suggested to use the same workaround as other apps:
|
||||
// (https://github.com/PhilippC/keepass2android/issues/747#issuecomment-622946085)
|
||||
//force HTTP1.1
|
||||
builder.protocols(Arrays.asList(Protocol.HTTP_1_1));
|
||||
|
||||
OkHttpClient client = builder.build();
|
||||
|
||||
|
||||
@@ -503,7 +516,7 @@ public class WebDavStorage extends JavaFileStorageBase {
|
||||
|
||||
@Override
|
||||
public void prepareFileUsage(Context appContext, String path) {
|
||||
//nothing to do
|
||||
this.appContext = appContext;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +33,10 @@ public class Kp2aDialog extends Activity {
|
||||
|
||||
final ArrayList<StringForTyping> items = new ArrayList<StringForTyping>();
|
||||
|
||||
|
||||
|
||||
List<StringForTyping> availableFields = keepass2android.kbbridge.KeyboardData.availableFields;
|
||||
for (StringForTyping entry : availableFields) {
|
||||
items.add(entry.clone());
|
||||
}
|
||||
|
||||
StringForTyping openOrChangeEntry = new StringForTyping();
|
||||
if (keepass2android.kbbridge.KeyboardData.entryName == null)
|
||||
|
||||
@@ -21,100 +21,6 @@ using File = System.IO.File;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
|
||||
public static class Kp2aLog
|
||||
{
|
||||
private static bool? _logToFile;
|
||||
|
||||
private static object _fileLocker = new object();
|
||||
|
||||
public static void Log(string message)
|
||||
{
|
||||
if (message != null)
|
||||
Android.Util.Log.Debug("KP2A", message);
|
||||
if (LogToFile)
|
||||
{
|
||||
lock (_fileLocker)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var streamWriter = System.IO.File.AppendText(LogFilename))
|
||||
{
|
||||
string stringToLog = DateTime.Now + ":" + DateTime.Now.Millisecond + " -- " + message;
|
||||
streamWriter.WriteLine(stringToLog);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Android.Util.Log.Debug("KP2A", "Couldn't write to log file. " + e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static string LogFilename
|
||||
{
|
||||
get { return Application.Context.FilesDir.CanonicalPath + "/keepass2android.log"; }
|
||||
}
|
||||
|
||||
private static bool LogToFile
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_logToFile == null)
|
||||
_logToFile = System.IO.File.Exists(LogFilename);
|
||||
return (bool)_logToFile;
|
||||
}
|
||||
}
|
||||
public static event EventHandler<Exception> OnUnexpectedError;
|
||||
|
||||
public static void LogUnexpectedError(Exception exception)
|
||||
{
|
||||
Log(exception.ToString());
|
||||
if (OnUnexpectedError != null)
|
||||
OnUnexpectedError(null, exception);
|
||||
}
|
||||
|
||||
public static void CreateLogFile()
|
||||
{
|
||||
if (!System.IO.File.Exists(LogFilename))
|
||||
{
|
||||
System.IO.File.Create(LogFilename).Dispose();
|
||||
_logToFile = true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void FinishLogFile()
|
||||
{
|
||||
if (System.IO.File.Exists(LogFilename))
|
||||
{
|
||||
_logToFile = false;
|
||||
int count = 0;
|
||||
while (System.IO.File.Exists(LogFilename + "." + count))
|
||||
count++;
|
||||
System.IO.File.Move(LogFilename, LogFilename + "." + count);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void SendLog(Context ctx)
|
||||
{
|
||||
if (!System.IO.File.Exists(LogFilename))
|
||||
return;
|
||||
Intent sendIntent = new Intent();
|
||||
sendIntent.SetAction(Intent.ActionSend);
|
||||
sendIntent.PutExtra(Intent.ExtraText, File.ReadAllText(LogFilename));
|
||||
sendIntent.PutExtra(Intent.ExtraEmail, "crocoapps@gmail.com");
|
||||
sendIntent.PutExtra(Intent.ExtraSubject, "Keepass2Android log");
|
||||
sendIntent.SetType("text/plain");
|
||||
ctx.StartActivity(Intent.CreateChooser(sendIntent, "Send log to..."));
|
||||
}
|
||||
}
|
||||
public interface IBiometricAuthCallback
|
||||
{
|
||||
void OnBiometricAuthSucceeded();
|
||||
@@ -215,6 +121,7 @@ namespace keepass2android
|
||||
get
|
||||
{
|
||||
var result = BiometricManager.From(Activity).CanAuthenticate();
|
||||
Kp2aLog.Log("BiometricHardware available = " + result);
|
||||
return result == BiometricManager.BiometricSuccess
|
||||
|| result == BiometricManager.BiometricErrorNoneEnrolled;
|
||||
}
|
||||
|
||||
@@ -497,7 +497,7 @@ namespace keepass2android
|
||||
ActionOnFinish closeOrShowError = new ActionOnFinish(this, (success, message, activity) => {
|
||||
if (success)
|
||||
{
|
||||
activity.Finish();
|
||||
activity?.Finish();
|
||||
} else
|
||||
{
|
||||
OnFinish.DisplayMessage(activity, message, true);
|
||||
@@ -505,6 +505,9 @@ namespace keepass2android
|
||||
State.EditMode.InitializeEntry(State.Entry);
|
||||
}
|
||||
});
|
||||
//make sure we can close the EntryEditActivity activity even if the app went to background till we get to the OnFinish Action
|
||||
closeOrShowError.AllowInactiveActivity = true;
|
||||
|
||||
|
||||
ActionOnFinish afterAddEntry = new ActionOnFinish(this, (success, message, activity) =>
|
||||
{
|
||||
|
||||
@@ -463,7 +463,7 @@ namespace keepass2android
|
||||
new AlertDialog.Builder(this)
|
||||
.SetTitle(Resource.String.autofill_enable)
|
||||
.SetMessage(Resource.String.autofill_enable_failed)
|
||||
.SetPositiveButton(Resource.String.ok, (o, eventArgs) => { })
|
||||
.SetPositiveButton(Resource.String.Ok, (o, eventArgs) => { })
|
||||
.Show();
|
||||
const string autofillservicewasenabled = "AutofillServiceWasEnabled";
|
||||
_prefs.Edit().PutBoolean(autofillservicewasenabled, true).Commit();
|
||||
@@ -1239,7 +1239,7 @@ namespace keepass2android
|
||||
{
|
||||
Handler.Post(() =>
|
||||
{
|
||||
Toast.MakeText(ActiveActivity, "Unrecoverable error: " + Message, ToastLength.Long).Show();
|
||||
Toast.MakeText(ActiveActivity ?? Application.Context, "Unrecoverable error: " + Message, ToastLength.Long).Show();
|
||||
});
|
||||
|
||||
App.Kp2a.Lock(false);
|
||||
|
||||
@@ -575,15 +575,13 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
int count = 1;
|
||||
|
||||
|
||||
|
||||
private string mDrawerTitle;
|
||||
private MeasuringRelativeLayout.MeasureArgs _measureArgs;
|
||||
private ActivityDesign _activityDesign;
|
||||
private BiometricDecryption _biometricDec;
|
||||
private bool _fingerprintPermissionGranted;
|
||||
private PasswordActivityBroadcastReceiver _intentReceiver;
|
||||
private PasswordActivityBroadcastReceiver _intentReceiver;
|
||||
private int _appnameclickCount;
|
||||
|
||||
|
||||
|
||||
@@ -80,34 +80,112 @@
|
||||
</intent-filter>
|
||||
|
||||
|
||||
<intent-filter android:label="@string/app_name">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="file" />
|
||||
<data android:mimeType="*/*" />
|
||||
<data android:host="*" />
|
||||
<data android:pathPattern=".*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
</intent-filter>
|
||||
<!-- intent filter for opening database files
|
||||
Note that this stopped working nicely with Android 7, see e.g. https://stackoverflow.com/a/26635162/292233
|
||||
KP2A was using
|
||||
<data android:scheme="content" />
|
||||
<data android:mimeType="*/*" />
|
||||
previously, but that leaded to complaints by users saying KP2A is showing up way too often, even when opening contacts and the like.
|
||||
|
||||
This is why this was reduced content with mimeType=application/octet-stream or content with pathPattern .
|
||||
|
||||
The scheme=file is still there for old OS devices. It's also queried by apps like Dropbox to find apps for a certain file type.
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<!-- This intent filter is for apps which use content with a URI containing the extension but no specific mimeType, e.g. ASTRO file manager -->
|
||||
|
||||
<intent-filter android:label="@string/app_name">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="content" />
|
||||
<data android:mimeType="*/*" />
|
||||
<data android:host="*" />
|
||||
<data android:pathPattern=".*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- This intent filter is for apps which use content with a URI not containing the extension but at least specify mimeType=application/octet-stream, e.g. GoogleDrive or FolderSync -->
|
||||
<intent-filter android:label="@string/app_name">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="content" />
|
||||
<data android:mimeType="application/octet-stream" />
|
||||
<data android:host="*" />
|
||||
</intent-filter>
|
||||
|
||||
|
||||
<!-- This intent filter is for old OS versions (Android 6 and below) or for apps explicitly querying intents for a certain file:-URI -->
|
||||
<intent-filter android:label="@string/app_name">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="file" />
|
||||
<data android:mimeType="*/*" />
|
||||
<data android:host="*" />
|
||||
<data android:pathPattern=".*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
</intent-filter>
|
||||
|
||||
|
||||
<intent-filter android:label="@string/kp2a_findUrl">
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
|
||||
@@ -85,7 +85,6 @@
|
||||
<action android:name="kp2a.action.SelectCurrentDbActivity" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
|
||||
|
||||
<intent-filter android:label="@string/app_name">
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
@@ -95,12 +94,27 @@
|
||||
|
||||
<data android:mimeType="application/*" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- intent filter for opening database files
|
||||
Note that this stopped working nicely with Android 7, see e.g. https://stackoverflow.com/a/26635162/292233
|
||||
KP2A was using
|
||||
<data android:scheme="content" />
|
||||
<data android:mimeType="*/*" />
|
||||
previously, but that leaded to complaints by users saying KP2A is showing up way too often, even when opening contacts and the like.
|
||||
|
||||
This is why this was reduced content with mimeType=application/octet-stream or content with pathPattern .
|
||||
|
||||
The scheme=file is still there for old OS devices. It's also queried by apps like Dropbox to find apps for a certain file type.
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<!-- This intent filter is for apps which use content with a URI containing the extension but no specific mimeType, e.g. ASTRO file manager -->
|
||||
|
||||
<intent-filter android:label="@string/app_name">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="file" />
|
||||
<data android:scheme="content" />
|
||||
<data android:mimeType="*/*" />
|
||||
<data android:host="*" />
|
||||
@@ -135,7 +149,59 @@
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
</intent-filter>
|
||||
<intent-filter android:label="@string/kp2a_findUrl">
|
||||
|
||||
<!-- This intent filter is for apps which use content with a URI not containing the extension but at least specify mimeType=application/octet-stream, e.g. GoogleDrive or FolderSync -->
|
||||
<intent-filter android:label="@string/app_name">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="content" />
|
||||
<data android:mimeType="application/octet-stream" />
|
||||
<data android:host="*" />
|
||||
</intent-filter>
|
||||
|
||||
|
||||
<!-- This intent filter is for old OS versions (Android 6 and below) or for apps explicitly querying intents for a certain file:-URI -->
|
||||
<intent-filter android:label="@string/app_name">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="file" />
|
||||
<data android:mimeType="*/*" />
|
||||
<data android:host="*" />
|
||||
<data android:pathPattern=".*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:label="@string/kp2a_findUrl">
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="text/plain" />
|
||||
|
||||
@@ -69,11 +69,26 @@
|
||||
<data android:mimeType="application/*" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- intent filter for opening database files
|
||||
Note that this stopped working nicely with Android 7, see e.g. https://stackoverflow.com/a/26635162/292233
|
||||
KP2A was using
|
||||
<data android:scheme="content" />
|
||||
<data android:mimeType="*/*" />
|
||||
previously, but that leaded to complaints by users saying KP2A is showing up way too often, even when opening contacts and the like.
|
||||
|
||||
This is why this was reduced content with mimeType=application/octet-stream or content with pathPattern .
|
||||
|
||||
The scheme=file is still there for old OS devices. It's also queried by apps like Dropbox to find apps for a certain file type.
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<!-- This intent filter is for apps which use content with a URI containing the extension but no specific mimeType, e.g. ASTRO file manager -->
|
||||
|
||||
<intent-filter android:label="@string/app_name">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="file" />
|
||||
<data android:scheme="content" />
|
||||
<data android:mimeType="*/*" />
|
||||
<data android:host="*" />
|
||||
@@ -108,6 +123,58 @@
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- This intent filter is for apps which use content with a URI not containing the extension but at least specify mimeType=application/octet-stream, e.g. GoogleDrive or FolderSync -->
|
||||
<intent-filter android:label="@string/app_name">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="content" />
|
||||
<data android:mimeType="application/octet-stream" />
|
||||
<data android:host="*" />
|
||||
</intent-filter>
|
||||
|
||||
|
||||
<!-- This intent filter is for old OS versions (Android 6 and below) or for apps explicitly querying intents for a certain file:-URI -->
|
||||
<intent-filter android:label="@string/app_name">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="file" />
|
||||
<data android:mimeType="*/*" />
|
||||
<data android:host="*" />
|
||||
<data android:pathPattern=".*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbp" />
|
||||
<data android:pathPattern=".*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdbx" />
|
||||
<data android:pathPattern=".*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.kdb" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
|
||||
@@ -62,10 +62,11 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<RelativeLayout
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:layout_weight="1"
|
||||
style="@style/EntryEditSingleLine_TextInputLayout">
|
||||
<EditText
|
||||
android:id="@+id/entry_password"
|
||||
@@ -103,7 +104,7 @@
|
||||
android:src="@drawable/ic_plus_button"
|
||||
android:background="?android:selectableItemBackground" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
<EditText
|
||||
android:id="@+id/entry_confpassword"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -138,12 +138,10 @@
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:text="@string/hint_login_pass" />
|
||||
<RelativeLayout
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/password_edit"
|
||||
android:layout_width="match_parent"
|
||||
@@ -152,6 +150,7 @@
|
||||
android:paddingTop="2dp"
|
||||
android:singleLine="true"
|
||||
android:inputType="textPassword"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="sans-serif"
|
||||
android:hint="@string/hint_login_pass"
|
||||
android:importantForAccessibility="no"/>
|
||||
@@ -180,8 +179,8 @@
|
||||
android:scaleType="fitXY"
|
||||
android:background="?android:selectableItemBackground" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/keyfileLine"
|
||||
android:layout_width="fill_parent"
|
||||
|
||||
@@ -31,6 +31,7 @@ using Java.IO;
|
||||
using KeePassLib.Serialization;
|
||||
using Keepass2android.Pluginsdk;
|
||||
using keepass2android.Io;
|
||||
using Console = System.Console;
|
||||
using Environment = Android.OS.Environment;
|
||||
|
||||
namespace keepass2android
|
||||
@@ -302,6 +303,16 @@ namespace keepass2android
|
||||
|
||||
private void EditFileEntry(string filename, IOConnectionInfo newConnectionInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
App.Kp2a.GetFileStorage(newConnectionInfo);
|
||||
}
|
||||
catch (NoFileStorageFoundException)
|
||||
{
|
||||
Toast.MakeText(this, "Don't know how to handle " + newConnectionInfo.Path, ToastLength.Long).Show();
|
||||
return;
|
||||
}
|
||||
|
||||
_dbHelper.CreateFile(newConnectionInfo, _dbHelper.GetKeyFileForFile(filename), false);
|
||||
_dbHelper.DeleteFile(filename);
|
||||
|
||||
|
||||
@@ -1888,7 +1888,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentFTP">
|
||||
<Version>31.3.1</Version>
|
||||
<Version>32.4.3</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Bcl">
|
||||
<Version>1.1.10</Version>
|
||||
|
||||
@@ -826,8 +826,18 @@ namespace keepass2android
|
||||
//must be enabled in settings first
|
||||
Toast.MakeText(this, Resource.String.please_activate_keyboard, ToastLength.Long).Show();
|
||||
Intent settingsIntent = new Intent(Android.Provider.Settings.ActionInputMethodSettings);
|
||||
settingsIntent.SetFlags(ActivityFlags.NewTask);
|
||||
StartActivity(settingsIntent);
|
||||
try
|
||||
{
|
||||
settingsIntent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ExcludeFromRecents);
|
||||
StartActivity(settingsIntent);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//seems like on Huawei devices this call can fail.
|
||||
Kp2aLog.LogUnexpectedError(e);
|
||||
Toast.MakeText(this, "Failed to switch keyboard.", ToastLength.Long).Show();
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -839,13 +849,24 @@ namespace keepass2android
|
||||
ActivityManager.RunningAppProcessInfo appProcessInfo = new ActivityManager.RunningAppProcessInfo();
|
||||
ActivityManager.GetMyMemoryState(appProcessInfo);
|
||||
//at least on Samsung devices, we always need the helper activity
|
||||
mustUseHelperActivity = (appProcessInfo.Importance != Importance.Foreground) || (Build.Manufacturer != "Google");
|
||||
mustUseHelperActivity = true;// TODO enable again (appProcessInfo.Importance != Importance.Foreground) || (Build.Manufacturer != "Google");
|
||||
}
|
||||
if (mustUseHelperActivity)
|
||||
{
|
||||
Intent switchImeIntent = new Intent(this, typeof(SwitchImeActivity));
|
||||
switchImeIntent.SetFlags(ActivityFlags.NewTask);
|
||||
StartActivity(switchImeIntent);
|
||||
try
|
||||
{
|
||||
Intent switchImeIntent = new Intent(this, typeof(SwitchImeActivity));
|
||||
switchImeIntent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ExcludeFromRecents);
|
||||
StartActivity(switchImeIntent);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//seems like on Huawei devices this call can fail.
|
||||
Kp2aLog.LogUnexpectedError(e);
|
||||
Toast.MakeText(this, "Failed to switch keyboard.", ToastLength.Long).Show();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -897,7 +918,7 @@ namespace keepass2android
|
||||
if (App.Kp2a.LastOpenedEntry == null)
|
||||
{
|
||||
Intent i = new Intent(context, typeof(AppKilledInfo));
|
||||
i.SetFlags(ActivityFlags.ClearTask | ActivityFlags.NewTask);
|
||||
i.SetFlags(ActivityFlags.ClearTask | ActivityFlags.NewTask | ActivityFlags.ExcludeFromRecents);
|
||||
context.StartActivity(i);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ namespace keepass2android.services
|
||||
protected override void HandleSaveRequest(StructureParser parser, string query)
|
||||
{
|
||||
var intent = new Intent(this, typeof(SelectCurrentDbActivity));
|
||||
intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTop | ActivityFlags.SingleTop);
|
||||
|
||||
|
||||
Dictionary<string, string> outputFields = new Dictionary<string, string>();
|
||||
foreach (var p in parser.ClientFormData.HintMap)
|
||||
|
||||
@@ -235,8 +235,11 @@ namespace keepass2android
|
||||
var dbname = kpDatabase.Name;
|
||||
if (String.IsNullOrEmpty(dbname))
|
||||
{
|
||||
//todo: if paranoid ("don't remember recent files") return "***"
|
||||
dbname = App.Kp2a.GetFileStorage(kpDatabase.IOConnectionInfo).GetFilenameWithoutPathAndExt(kpDatabase.IOConnectionInfo);
|
||||
//if paranoid ("don't remember recent files")return "***"
|
||||
if (!App.Kp2a.GetBooleanPreference(PreferenceKey.remember_keyfile))
|
||||
return "***";
|
||||
dbname = UrlUtil.StripExtension(
|
||||
UrlUtil.GetFileName(App.Kp2a.GetFileStorage(kpDatabase.IOConnectionInfo).GetDisplayName(kpDatabase.IOConnectionInfo)));
|
||||
}
|
||||
if (displayString != "")
|
||||
displayString = displayString + ", ";
|
||||
|
||||
Reference in New Issue
Block a user