integrated new storage implementations in C# app.

Extended file chooser to show error messages in case of connection failure. Important for new FTP/WebDav implementations when browsing fails.
This commit is contained in:
Philipp Crocoll 2016-11-28 11:01:22 +01:00
parent b8de15410d
commit 31f02eca61
69 changed files with 618 additions and 318 deletions

View File

@ -55,8 +55,8 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<LibraryProjectZip Include="..\java\android-filechooser-AS\app\build\outputs\aar\app-debug.aar">
<Link>Jars\app-debug.aar</Link>
<LibraryProjectZip Include="..\java\android-filechooser-AS\app\build\outputs\aar\android-filechooser-release.aar">
<Link>Jars\android-filechooser-release.aar</Link>
</LibraryProjectZip>
<None Include="Jars\AboutJars.txt" />
<None Include="Additions\AboutAdditions.txt" />

View File

@ -64,8 +64,8 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<LibraryProjectZip Include="..\java\JavaFileStorage\app\build\outputs\aar\app-debug.aar">
<Link>Jars\app-debug.aar</Link>
<LibraryProjectZip Include="..\java\JavaFileStorage\app\build\outputs\aar\JavaFileStorage-debug.aar">
<Link>Jars\JavaFileStorage-debug.aar</Link>
</LibraryProjectZip>
<None Include="Jars\AboutJars.txt" />
<None Include="Additions\AboutAdditions.txt" />
@ -75,81 +75,6 @@
<TransformFile Include="Transforms\EnumFields.xml" />
<TransformFile Include="Transforms\EnumMethods.xml" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\json_simple-1.1.jar">
<Link>Jars\json_simple-1.1.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\google-api-client-1.16.0-rc.jar">
<Link>Jars\google-api-client-1.16.0-rc.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\google-api-client-android-1.16.0-rc.jar">
<Link>Jars\google-api-client-android-1.16.0-rc.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\google-api-services-drive-v2-rev102-1.16.0-rc.jar">
<Link>Jars\google-api-services-drive-v2-rev102-1.16.0-rc.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\google-http-client-1.16.0-rc.jar">
<Link>Jars\google-http-client-1.16.0-rc.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\google-http-client-android-1.16.0-rc.jar">
<Link>Jars\google-http-client-android-1.16.0-rc.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\google-http-client-gson-1.16.0-rc.jar">
<Link>Jars\google-http-client-gson-1.16.0-rc.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\google-http-client-jackson-1.16.0-rc.jar">
<Link>Jars\google-http-client-jackson-1.16.0-rc.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\google-http-client-jackson2-1.16.0-rc.jar">
<Link>Jars\google-http-client-jackson2-1.16.0-rc.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\google-oauth-client-1.16.0-rc.jar">
<Link>Jars\google-oauth-client-1.16.0-rc.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\gson-2.1.jar">
<Link>Jars\gson-2.1.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\httpmime-4.0.3.jar">
<Link>Jars\httpmime-4.0.3.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\jackson-core-2.1.3.jar">
<Link>Jars\jackson-core-2.1.3.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\jackson-core-asl-1.9.11.jar">
<Link>Jars\jackson-core-asl-1.9.11.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\jsr305-1.3.9.jar">
<Link>Jars\jsr305-1.3.9.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.Bindings.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
@ -164,4 +89,76 @@
<Visible>False</Visible>
</XamarinComponentReference>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\okhttp-3.4.1.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\okhttp-digest-1.7.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\dropbox-core-sdk-2.1.1.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gson-2.3.1.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\msa-auth-0.8.6\classes-msa-auth.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\onedrive-sdk-android-1.2.2\classes-onedrive-sdk.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\adal-1.1.19\classes-adal.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\commons-logging-1.1.1.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\google-api-client-1.16.0-rc.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\google-api-client-android-1.16.0-rc.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\google-api-services-drive-v2-rev102-1.16.0-rc.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\google-http-client-1.16.0-rc.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\google-http-client-android-1.16.0-rc.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\google-http-client-jackson-1.16.0-rc.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\google-http-client-jackson2-1.16.0-rc.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\google-oauth-client-1.16.0-rc.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\httpclient-4.0.3.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\httpcore-4.0.1.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\httpmime-4.0.3.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\json_simple-1.1.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\jsr305-1.3.9.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\google-http-client-gson-1.16.0-rc.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\jackson-core-2.7.4.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\okio-1.9.0.jar" />
</ItemGroup>
</Project>

View File

@ -6,31 +6,11 @@
This sample removes the method: android.support.v4.content.CursorLoader.loadInBackground:
<remove-node path="/api/package[@name='android.support.v4.content']/class[@name='CursorLoader']/method[@name='loadInBackground']" />
-->
<remove-node path="/api/package[starts-with(@name, 'org.apache')]" />
<remove-node path="/api/package[starts-with(@name, 'org.codehaus')]" />
<remove-node path="/api/package[starts-with(@name, 'com.fasterxml')]" />
<remove-node path="/api/package[starts-with(@name, 'com.google')]" />
<remove-node path="/api/package[@name='org.apache.http']" />
<remove-node path="/api/package[@name='org.apache.http.entity']" />
<remove-node path="/api/package[@name='org.apache.http.impl']" />
<remove-node path="/api/package[@name='org.apache.http.impl.client']" />
<remove-node path="/api/package[@name='org.apache.http.impl.entity']" />
<remove-node path="/api/package[@name='org.apache.http.impl.io']" />
<remove-node path="/api/package[@name='org.apache.http.io']" />
<remove-node path="/api/package[@name='org.apache.http.message']" />
<remove-node path="/api/package[@name='org.apache.http.params']" />
<remove-node path="/api/package[@name='org.apache.http.protocol']" />
<remove-node path="/api/package[@name='org.apache.http.ui']" />
<remove-node path="/api/package[@name='com.jcraft.jsch']" />
<remove-node path="/api/package[@name='com.jcraft.jsch.jce']" />
<remove-node path="/api/package[@name='com.jcraft.jsch.jcraft']" />
<remove-node path="/api/package[@name='com.jcraft.jzlib']" />
<remove-node path="/api/package[@name='com.microsoft.live']" />
<remove-node path="/api/package[@name='com.dropbox.client']" />
<remove-node path="/api/package[@name='com.dropbox.client2']" />
<remove-node path="/api/package[@name='com.dropbox.client2.session']" />
<remove-node path="/api/package[@name='com.dropbox.client2.android']" />
<remove-node path="/api/package[@name='com.dropbox.client2.jsonextract']" />
<remove-node path="/api/package[@name='com.dropbox.client2.exception']" />
<remove-node path="/api/package[@name='keepass2android.javafilestorage.webdav']" />
<remove-node path="/api/package[@name='keepass2android.javafilestorage.onedrive']" />
</metadata>

View File

@ -9,6 +9,7 @@ using KeePassLib;
using KeePassLib.Keys;
using KeePassLib.Serialization;
using keepass2android.Io;
using Keepass2android.Javafilestorage;
namespace keepass2android
{
@ -28,7 +29,7 @@ namespace keepass2android
/// Interface through which Activities and the logic layer can access some app specific functionalities and Application static data
/// </summary>
/// This also contains methods which are UI specific and should be replacable for testing.
public interface IKp2aApp: ICertificateValidationHandler
public interface IKp2aApp : ICertificateValidationHandler
{
/// <summary>
/// Locks the currently open database, quicklocking if available (unless false is passed for allowQuickUnlock)
@ -106,5 +107,6 @@ namespace keepass2android
bool CheckForDuplicateUuids { get; }
ICertificateErrorHandler CertificateErrorHandler { get; }
}
}

View File

@ -6,7 +6,7 @@ namespace keepass2android.Io
public partial class DropboxFileStorage: JavaFileStorage
{
public DropboxFileStorage(Context ctx, IKp2aApp app) :
base(new Keepass2android.Javafilestorage.DropboxFileStorage(ctx, AppKey, AppSecret), app)
base(new Keepass2android.Javafilestorage.DropboxV2Storage(ctx, AppKey, AppSecret), app)
{
}
@ -16,7 +16,7 @@ namespace keepass2android.Io
public partial class DropboxAppFolderFileStorage: JavaFileStorage
{
public DropboxAppFolderFileStorage(Context ctx, IKp2aApp app) :
base(new Keepass2android.Javafilestorage.DropboxAppFolderFileStorage(ctx, AppKey, AppSecret), app)
base(new Keepass2android.Javafilestorage.DropboxV2AppFolderStorage(ctx, AppKey, AppSecret), app)
{
}

View File

@ -21,7 +21,7 @@ namespace keepass2android.Io
{
protected string Protocol { get { return _jfs.ProtocolId; } }
public IEnumerable<string> SupportedProtocols { get { yield return Protocol; } }
public virtual IEnumerable<string> SupportedProtocols { get { yield return Protocol; } }
private readonly IJavaFileStorage _jfs;

View File

@ -1,31 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using KeePassLib.Serialization;
#if !EXCLUDE_JAVAFILESTORAGE
using Keepass2android.Javafilestorage;
namespace keepass2android.Io
{
public class SkyDriveFileStorage: JavaFileStorage
{
private const string ClientId = "000000004010C234";
public SkyDriveFileStorage(Context ctx, IKp2aApp app) :
base(new Keepass2android.Javafilestorage.SkyDriveFileStorage(ClientId, ctx), app)
{
}
}
}
#endif

View File

@ -96,7 +96,8 @@
<Compile Include="Io\NetFtpFileStorage.cs" />
<Compile Include="Io\OfflineSwitchableFileStorage.cs" />
<Compile Include="Io\SftpFileStorage.cs" />
<Compile Include="Io\SkyDriveFileStorage.cs" />
<Compile Include="Io\OneDriveFileStorage.cs" />
<Compile Include="Io\WebDavFileStorage.cs" />
<Compile Include="IProgressDialog.cs" />
<Compile Include="PreferenceKey.cs" />
<Compile Include="SelectStorageLocationActivityBase.cs" />

View File

@ -33,14 +33,14 @@ dependencies {
compile 'com.google.android.gms:play-services:4.0.30'
compile('com.google.api-client:google-api-client-xml:1.17.0-rc') {
/* compile('com.google.api-client:google-api-client-xml:1.16.0-rc') {
exclude group: 'com.google.android.google-play-services'
}*/
compile 'com.google.http-client:google-http-client-gson:1.16.0-rc'
compile('com.google.api-client:google-api-client-android:1.16.0-rc') {
exclude group: 'com.google.android.google-play-services'
}
compile 'com.google.http-client:google-http-client-gson:1.17.0-rc'
compile('com.google.api-client:google-api-client-android:1.17.0-rc') {
exclude group: 'com.google.android.google-play-services'
}
compile 'com.google.apis:google-api-services-drive:v2-rev105-1.17.0-rc'
compile 'com.google.apis:google-api-services-drive:v2-rev102-1.16.0-rc'
//compile 'com.dropbox.core:dropbox-core-sdk:2.0.1'
//compile group: 'com.dropbox.core', name: 'dropbox-core-sdk', version: '0-SNAPSHOT', changing: true
@ -52,7 +52,6 @@ dependencies {
compile ('com.onedrive.sdk:onedrive-sdk-android:1.2+') {
transitive = false
}
// Include the gson dependency
compile ('com.google.code.gson:gson:2.3.1')
compile ('com.microsoft.services.msa:msa-auth:0.8.+')
compile ('com.microsoft.aad:adal:1.1.+')

View File

@ -63,7 +63,7 @@ public class OneDriveStorage extends JavaFileStorageBase
@Override
public void startSelectFile(FileStorageSetupInitiatorActivity activity, boolean isForSave, int requestCode) {
initAuthenticator((Activity)activity);
initAuthenticator((Activity)activity.getActivity());
String path = getProtocolId()+":///";
Log.d("KP2AJ", "startSelectFile "+path+", connected: "+path);
@ -113,8 +113,8 @@ public class OneDriveStorage extends JavaFileStorageBase
@Override
public void prepareFileUsage(FileStorageSetupInitiatorActivity activity, String path, int requestCode, boolean alwaysReturnSuccess) {
initAuthenticator((Activity)activity);
if (isConnected((Activity)activity))
initAuthenticator((Activity)activity.getActivity());
if (isConnected((Activity)activity.getActivity()))
{
Intent intent = new Intent();
intent.putExtra(EXTRA_PATH, path);
@ -151,58 +151,7 @@ public class OneDriveStorage extends JavaFileStorageBase
@Override
public void onResume(final FileStorageSetupActivity activity) {
Log.d("KP2AJ", "onResume");
if (activity.getProcessName().equals(PROCESS_NAME_SELECTFILE))
activity.getState().putString(EXTRA_PATH, activity.getPath());
JavaFileStorage.FileStorageSetupActivity storageSetupAct = activity;
if (storageSetupAct.getState().containsKey("hasStartedAuth"))
{
Log.d("KP2AJ", "auth started");
if (oneDriveClient != null) {
Log.d("KP2AJ", "auth successful");
try {
finishActivityWithSuccess(activity);
return;
} catch (Exception e) {
Log.d("KP2AJ", "finish with error: " + e.toString());
finishWithError(activity, e);
return;
}
}
Log.i(TAG, "authenticating not succesful");
Intent data = new Intent();
data.putExtra(EXTRA_ERROR_MESSAGE, "authenticating not succesful");
((Activity)activity).setResult(Activity.RESULT_CANCELED, data);
((Activity)activity).finish();
}
else
{
Log.d("KP2AJ", "Starting auth");
new AsyncTask<Object, Object, Object>() {
@Override
protected Object doInBackground(Object... params) {
return buildClient((Activity)activity);
}
@Override
protected void onPostExecute(Object o) {
oneDriveClient = (IOneDriveClient) o;
finishActivityWithSuccess(activity);
}
}.execute();
storageSetupAct.getState().putBoolean("hasStartedAuth", true);
}
}
@ -375,8 +324,63 @@ public class OneDriveStorage extends JavaFileStorageBase
}
@Override
public void onStart(FileStorageSetupActivity activity) {
public void onStart(final FileStorageSetupActivity activity) {
Log.d("KP2AJ", "onStart");
if (activity.getProcessName().equals(PROCESS_NAME_SELECTFILE))
activity.getState().putString(EXTRA_PATH, activity.getPath());
JavaFileStorage.FileStorageSetupActivity storageSetupAct = activity;
if (oneDriveClient != null) {
Log.d("KP2AJ", "auth successful");
try {
finishActivityWithSuccess(activity);
return;
} catch (Exception e) {
Log.d("KP2AJ", "finish with error: " + e.toString());
finishWithError(activity, e);
return;
}
}
{
Log.d("KP2AJ", "Starting auth");
new AsyncTask<Object, Object, Object>() {
@Override
protected Object doInBackground(Object... params) {
try {
return buildClient((Activity) activity);
} catch (Exception e) {
return null;
}
}
@Override
protected void onPostExecute(Object o) {
if (o == null)
{
Log.i(TAG, "authenticating not successful");
Intent data = new Intent();
data.putExtra(EXTRA_ERROR_MESSAGE, "authenticating not succesful");
((Activity)activity).setResult(Activity.RESULT_CANCELED, data);
((Activity)activity).finish();
}
else
{
Log.i(TAG, "authenticating successful");
oneDriveClient = (IOneDriveClient) o;
finishActivityWithSuccess(activity);
}
}
}.execute();
}
}
@Override

View File

@ -22,7 +22,6 @@ import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
@ -36,6 +35,7 @@ import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import keepass2android.javafilestorage.webdav.ConnectionInfo;
import keepass2android.javafilestorage.webdav.DecoratedTrustManager;
import keepass2android.javafilestorage.webdav.PropfindXmlParser;
import keepass2android.javafilestorage.webdav.WebDavUtil;
@ -61,12 +61,6 @@ public class WebDavStorage extends JavaFileStorageBase {
return scheme + "://" + encode(username)+":"+encode(password)+"@"+url;
}
static class ConnectionInfo {
String URL;
String username;
String password;
}
private ConnectionInfo splitStringToConnectionInfo(String filename)
throws UnsupportedEncodingException {
ConnectionInfo ci = new ConnectionInfo();

View File

@ -30,21 +30,41 @@
</component>
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file leaf-file-name="build.gradle" pinned="false" current-in-tab="false">
<file leaf-file-name="build.gradle" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/build.gradle">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="18" column="4" selection-start-line="18" selection-start-column="4" selection-end-line="18" selection-end-column="4" />
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="build.gradle" pinned="false" current-in-tab="true">
<file leaf-file-name="build.gradle" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/app/build.gradle">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.1218638">
<caret line="4" column="29" selection-start-line="4" selection-start-column="29" selection-end-line="4" selection-end-column="29" />
<state vertical-scroll-proportion="0.0">
<caret line="16" column="5" selection-start-line="16" selection-start-column="5" selection-end-line="16" selection-end-column="5" />
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="local.properties" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/local.properties">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="gradle.properties" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/gradle.properties">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="-0.0">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
@ -71,6 +91,8 @@
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/app/build.gradle" />
<option value="$PROJECT_DIR$/gradle.properties" />
<option value="$PROJECT_DIR$/build.gradle" />
</list>
</option>
</component>
@ -106,8 +128,8 @@
</navigator>
<panes>
<pane id="Scratches" />
<pane id="Scope" />
<pane id="PackagesPane" />
<pane id="ProjectPane" />
<pane id="AndroidView">
<subPane>
<PATH>
@ -115,10 +137,24 @@
<option name="myItemId" value="android-filechooser-AS" />
<option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="Gradle Scripts" />
<option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidBuildScriptsGroupNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="android-filechooser-AS" />
<option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="android-filechooser-AS" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
</subPane>
</pane>
<pane id="ProjectPane" />
<pane id="Scope" />
</panes>
</component>
<component name="PropertiesComponent">
@ -363,7 +399,7 @@
</component>
<component name="ToolWindowManager">
<frame x="-8" y="-8" width="1382" height="744" extended-state="6" />
<editor active="false" />
<editor active="true" />
<layout>
<window_info id="Palette&#9;" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Designer" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
@ -379,11 +415,11 @@
<window_info id="Gradle Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Build Variants" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="true" content_ui="tabs" />
<window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32935154" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.32935154" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Gradle" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.24962178" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.24962178" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
@ -419,6 +455,14 @@
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/app/build.gradle">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="16" column="5" selection-start-line="16" selection-start-column="5" selection-end-line="16" selection-end-column="5" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/local.properties">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
@ -426,7 +470,7 @@
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/settings.gradle">
<entry file="file://$PROJECT_DIR$/gradle.properties">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
@ -452,8 +496,80 @@
</entry>
<entry file="file://$PROJECT_DIR$/app/build.gradle">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.1218638">
<caret line="4" column="29" selection-start-line="4" selection-start-column="29" selection-end-line="4" selection-end-column="29" />
<state vertical-scroll-proportion="0.0">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/settings.gradle">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/build.gradle">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="18" column="4" selection-start-line="18" selection-start-column="4" selection-end-line="18" selection-end-column="4" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/app/build.gradle">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/settings.gradle">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/app/build.gradle">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="16" column="5" selection-start-line="16" selection-start-column="5" selection-end-line="16" selection-end-column="5" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/settings.gradle">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/local.properties">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/gradle.properties">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/build.gradle">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>

View File

@ -1022,6 +1022,7 @@ public class FragmentFiles extends Fragment implements
* showCannotConnectToServiceAndWaitForTheUserToFinish().
*/
String errMsg = null;
boolean errorMessageInDialog = false;
@Override
protected Bundle doInBackground(Void... params) {
@ -1031,46 +1032,77 @@ public class FragmentFiles extends Fragment implements
Uri path = (Uri) (savedInstanceState != null ? savedInstanceState
.getParcelable(CURRENT_LOCATION) : null);
if (mRoot != null) {
Uri queryUri = BaseFile.genContentUriApi(mRoot.getAuthority())
.buildUpon()
.appendPath(BaseFile.CMD_CHECK_CONNECTION)
.appendQueryParameter(
BaseFile.PARAM_SOURCE,
mRoot.getLastPathSegment()).build();
Cursor cursor = getActivity().getContentResolver().query(
queryUri,
null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
errMsg = getString(R.string.afc_msg_cannot_connect_to_file_provider_service) + " " + cursor.getString(0);
errorMessageInDialog = true;
return null;
}
}
try
{
/*
* Selected file
*/
if (path == null) {
path = (Uri) getArguments().getParcelable(
FileChooserActivity.EXTRA_SELECT_FILE);
if (path != null
&& BaseFileProviderUtils.fileExists(getActivity(),
path))
path = BaseFileProviderUtils.getParentFile(
getActivity(), path);
}
if (path == null) {
path = (Uri) getArguments().getParcelable(
FileChooserActivity.EXTRA_SELECT_FILE);
if (path != null
&& BaseFileProviderUtils.fileExists(getActivity(),
path))
path = BaseFileProviderUtils.getParentFile(
getActivity(), path);
}
/*
* Rootpath
*/
if (path == null
|| !BaseFileProviderUtils.isDirectory(getActivity(),
path)) {
path = mRoot;
}
if (path == null
|| !BaseFileProviderUtils.isDirectory(getActivity(),
path)) {
path = mRoot;
}
/*
* Last location
*/
if (path == null
&& DisplayPrefs.isRememberLastLocation(getActivity())) {
String lastLocation = DisplayPrefs
.getLastLocation(getActivity());
if (lastLocation != null)
path = Uri.parse(lastLocation);
if (path == null
&& DisplayPrefs.isRememberLastLocation(getActivity())) {
String lastLocation = DisplayPrefs
.getLastLocation(getActivity());
if (lastLocation != null)
path = Uri.parse(lastLocation);
}
if (path == null
|| !BaseFileProviderUtils.isDirectory(getActivity(),
path))
path = BaseFileProviderUtils.getDefaultPath(
getActivity(),
path == null ? mFileProviderAuthority : path
.getAuthority());
}
catch (Exception ex)
{
errMsg = getString(R.string.afc_msg_cannot_connect_to_file_provider_service) + " " + ex.toString();
errorMessageInDialog = true;
return null;
}
if (path == null
|| !BaseFileProviderUtils.isDirectory(getActivity(),
path))
path = BaseFileProviderUtils.getDefaultPath(
getActivity(),
path == null ? mFileProviderAuthority : path
.getAuthority());
if (path == null)
return null;
@ -1110,8 +1142,25 @@ public class FragmentFiles extends Fragment implements
getLoaderManager().initLoader(mIdLoaderData, result,
FragmentFiles.this);
} else if (errMsg != null) {
Dlg.toast(getActivity(), errMsg, Dlg.LENGTH_SHORT);
getActivity().finish();
if (errorMessageInDialog)
{
Dlg.showError(getActivity(),
errMsg,
new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
getActivity().setResult(Activity.RESULT_FIRST_USER);
getActivity().finish();
}// onCancel()
});
}
else
{
Dlg.toast(getActivity(), errMsg, Dlg.LENGTH_SHORT);
getActivity().finish();
}
} else
showCannotConnectToServiceAndWaitForTheUserToFinish();
}// onPostExecute()
@ -1153,7 +1202,7 @@ public class FragmentFiles extends Fragment implements
@Override
public void onCancel(DialogInterface dialog) {
getActivity().setResult(Activity.RESULT_CANCELED);
getActivity().setResult(Activity.RESULT_FIRST_USER);
getActivity().finish();
}// onCancel()
});
@ -1812,8 +1861,10 @@ public class FragmentFiles extends Fragment implements
setCurrentLocation((Uri) result.getParcelable(PATH));
getLoaderManager().restartLoader(mIdLoaderData, result,
FragmentFiles.this);
} else if (errMsg != null)
} else if (errMsg != null) {
Dlg.toast(getActivity(), errMsg, Dlg.LENGTH_SHORT);
}
else
showCannotConnectToServiceAndWaitForTheUserToFinish();
}// onPostExecute()

View File

@ -216,6 +216,9 @@ public class BaseFileProviderUtils {
BaseFile.COLUMN_TYPE, BaseFile.COLUMN_MODIFICATION_TIME,
BaseFile.COLUMN_ICON_ID };
public static final String[] CONNECTION_CHECK_CURSOR_COLUMNS = {"error"};
/**
* Creates new cursor which holds default properties of a base file for
* client to access.

View File

@ -124,6 +124,7 @@ public class BaseFileContract {
*/
public static final String PATH_API = "api";
/*
* COMMANDS.
*/
@ -187,6 +188,9 @@ public class BaseFileContract {
*/
public static final String CMD_SHUTDOWN = "shutdown";
public static final String CMD_CHECK_CONNECTION = "check_connection";
/*
* PARAMETERS.
*/

View File

@ -51,6 +51,12 @@ public abstract class BaseFileProvider extends ContentProvider {
*/
protected static final int URI_API_COMMAND = 4;
/**
* Check if connection to the file service is ok.
*/
protected static final int URI_CHECK_CONNECTION = 5;
/**
* A {@link UriMatcher} instance.
*/
@ -79,8 +85,9 @@ public abstract class BaseFileProvider extends ContentProvider {
switch (URI_MATCHER.match(uri)) {
case URI_API:
case URI_API_COMMAND:
case URI_DIRECTORY:
return BaseFile.CONTENT_TYPE;
case URI_DIRECTORY :
case URI_CHECK_CONNECTION:
return BaseFile.CONTENT_TYPE;
case URI_FILE:
return BaseFile.CONTENT_ITEM_TYPE;

View File

@ -8,6 +8,7 @@ package keepass2android.kp2afilechooser;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@ -22,6 +23,7 @@ import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.MatrixCursor.RowBuilder;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.util.Log;
import group.pals.android.lib.ui.filechooser.R;
import group.pals.android.lib.ui.filechooser.providers.BaseFileProviderUtils;
@ -216,6 +218,41 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
}
}// query()
@Nullable
private MatrixCursor getCheckConnectionCursor(Uri uri) {
try
{
checkConnection(uri);
return null;
}
catch (Exception e)
{
MatrixCursor matrixCursor = new MatrixCursor(BaseFileProviderUtils.CONNECTION_CHECK_CURSOR_COLUMNS);
RowBuilder newRow = matrixCursor.newRow();
String message = e.getLocalizedMessage();
if (message == null)
message = e.getMessage();
if (message == null)
message = e.toString();
newRow.add(message);
return matrixCursor;
}
}
private void checkConnection(Uri uri) throws Exception {
try
{
String path = Uri.parse(
uri.getQueryParameter(BaseFile.PARAM_SOURCE)).toString();
getFileEntry(path);
}
catch (FileNotFoundException ex)
{
return;
}
}
/*
* UTILITIES
*/
@ -256,7 +293,7 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
{
String path = Uri.parse(
uri.getQueryParameter(BaseFile.PARAM_SOURCE)).toString();
uri.getQueryParameter(BaseFile.PARAM_SOURCE)).toString();
String parentPath = getParentPath(path);
@ -306,6 +343,9 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
// mMapInterruption.put(mMapInterruption.keyAt(i), true);
// }
} else if (BaseFile.CMD_CHECK_CONNECTION.equals(lastPathSegment))
{
return getCheckConnectionCursor(uri);
}
return matrixCursor;
@ -538,9 +578,15 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
if (Utils.doLog())
Log.d(CLASSNAME, "getFileEntryCached: not in cache :-( " + filename);
//it's not -> query the information.
FileEntry newEntry = getFileEntry(filename);
FileEntry newEntry ;
try {
//it's not -> query the information.
newEntry = getFileEntry(filename);
} catch (Exception e) {
e.printStackTrace();
return null;
}
if (!cacheBlockedFiles.contains(filename))
updateFileEntryCache(newEntry);
@ -729,7 +775,7 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
protected abstract FileEntry getFileEntry(String path);
protected abstract FileEntry getFileEntry(String path) throws Exception;
/**
* Lists all file inside {@code dirName}.

View File

@ -63,6 +63,37 @@ namespace keepass2android
#endif
}
private void ShowHttpDialog(Activity activity, Util.FileSelectedHandler onStartBrowse, Action onCancel, string defaultPath)
{
#if !EXCLUDE_JAVAFILESTORAGE && !NoNet
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
View dlgContents = activity.LayoutInflater.Inflate(Resource.Layout.httpcredentials, null);
builder.SetView(dlgContents);
builder.SetPositiveButton(Android.Resource.String.Ok,
(sender, args) =>
{
string host = dlgContents.FindViewById<EditText>(Resource.Id.http_url).Text;
string user = dlgContents.FindViewById<EditText>(Resource.Id.http_user).Text;
string password = dlgContents.FindViewById<EditText>(Resource.Id.http_password).Text;
string scheme = defaultPath.Substring(defaultPath.IndexOf("://", StringComparison.Ordinal));
if (host.Contains("://") == false)
host = scheme + "://" + host;
string httpPath = new Keepass2android.Javafilestorage.WebDavStorage(null).BuildFullPath(host, user,
password);
onStartBrowse(httpPath);
});
EventHandler<DialogClickEventArgs> evtH = new EventHandler<DialogClickEventArgs>((sender, e) => onCancel());
builder.SetNegativeButton(Android.Resource.String.Cancel, evtH);
builder.SetTitle(activity.GetString(Resource.String.enter_http_login_title));
Dialog dialog = builder.Create();
dialog.Show();
#endif
}
private void ShowFtpDialog(Activity activity, Util.FileSelectedHandler onStartBrowse, Action onCancel)
{
#if !NoNet
@ -89,7 +120,7 @@ namespace keepass2android
EventHandler<DialogClickEventArgs> evtH = new EventHandler<DialogClickEventArgs>((sender, e) => onCancel());
builder.SetNegativeButton(Android.Resource.String.Cancel, evtH);
builder.SetTitle(activity.GetString(Resource.String.enter_sftp_login_title));
builder.SetTitle(activity.GetString(Resource.String.enter_ftp_login_title));
Dialog dialog = builder.Create();
dialog.Show();
@ -100,9 +131,11 @@ namespace keepass2android
public void PerformManualFileSelect(string defaultPath)
{
if (defaultPath.StartsWith("sftp://"))
ShowSftpDialog(_activity, StartFileChooser, ReturnCancel);
ShowSftpDialog(_activity, ReturnFileOrStartFileChooser, ReturnCancel);
else if ((defaultPath.StartsWith("ftp://")) || (defaultPath.StartsWith("ftps://")))
ShowFtpDialog(_activity, StartFileChooser, ReturnCancel);
ShowFtpDialog(_activity, ReturnFileOrStartFileChooser, ReturnCancel);
else if ((defaultPath.StartsWith("http://")) || (defaultPath.StartsWith("https://")))
ShowHttpDialog(_activity, ReturnFileOrStartFileChooser, ReturnCancel, defaultPath);
else
{
Func<string, Dialog, bool> onOpen = OnOpenButton;
@ -118,6 +151,20 @@ namespace keepass2android
}
}
private bool ReturnFileOrStartFileChooser(string filename)
{
int lastSlashPos = filename.LastIndexOf('/');
int lastDotPos = filename.LastIndexOf('.');
if (lastSlashPos >= lastDotPos) //no dot after last slash or == in case neither / nor .
{
//looks like a folder.
return StartFileChooser(filename);
}
//looks like a file
IocSelected(IOConnectionInfo.FromPath(filename));
return true;
}
private void ReturnCancel()
{
if (OnCancel != null)

View File

@ -48,7 +48,10 @@ namespace keepass2android
//show all supported protocols:
foreach (IFileStorage fs in App.Kp2a.FileStorages)
_displayedProtocolIds.AddRange(fs.SupportedProtocols);
//this is there for legacy reasons, new protocol is onedrive
_displayedProtocolIds.Remove("skydrive");
//special handling for local files:
if (!Util.IsKitKatOrLater)
{

View File

@ -4,7 +4,7 @@
<permission android:description="@string/permission_desc" android:icon="@drawable/ic_launcher" android:label="KP2A internal file browsing" android:name="keepass2android.keepass2android_debug.permission.KP2aInternalFileBrowsing" android:protectionLevel="signature" />
<application android:label="keepass2android" android:icon="@drawable/ic_launcher">
<activity android:name="com.dropbox.client2.android.AuthActivity" android:launchMode="singleTask" android:configChanges="orientation|keyboard">
<activity android:name="com.dropbox.core.android.AuthActivity" android:launchMode="singleTask" android:configChanges="orientation|keyboard">
<intent-filter>
<data android:scheme="db-2gormiq7iq1jls1" />
<action android:name="android.intent.action.VIEW" />

View File

@ -7,7 +7,7 @@
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" />
<permission android:description="@string/permission_desc" android:icon="@drawable/ic_launcher_online" android:label="KP2A internal file browsing" android:name="keepass2android.keepass2android.permission.KP2aInternalFileBrowsing" android:protectionLevel="signature" />
<application android:label="keepass2android" android:icon="@drawable/ic_launcher_online">
<activity android:name="com.dropbox.client2.android.AuthActivity" android:launchMode="singleTask" android:configChanges="orientation|keyboard">
<activity android:name="com.dropbox.core.android.AuthActivity" android:launchMode="singleTask" android:configChanges="orientation|keyboard">
<intent-filter>
<data android:scheme="db-i8shu7v1hgh7ynt" />
<action android:name="android.intent.action.VIEW" />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -358,7 +358,7 @@
<string name="filestoragename_dropboxKP2A">Dropbox (KP2A папка)</string>
<string name="filestoragehelp_dropboxKP2A">Ако не искате да дадете KP2A достъп до пълен живея, можете да изберете тази опция. Тя ще поиска достъп само до папката приложения/Keepass2Android. Това е особено подходящ, когато създавате нова база данни. Ако вече имате база данни, щракнете върху тази опция, за да създаде папката, след което поставете вашия файл в папката (от вашия компютър) и след това изберете тази опция отново за отваряне на файла.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH прехвърляне на файлове)</string>
<string name="filestorage_setup_title">Файла достъп инициализация</string>
<string name="database_location">Database местоположение</string>

View File

@ -425,7 +425,7 @@ Això emmagatzemarà la contrasenya mestra d\'aquest
<string name="filestoragename_dropboxKP2A">Dropbox (carpeta de KP2A)</string>
<string name="filestoragehelp_dropboxKP2A">Si no voleu donar accés KP2A al seu Dropbox complet, podeu seleccionar aquesta opció. Es sol·licitarà només l\'accés a la carpeta Apps/Keepass2Android. Això és especialment adequat quan es crea una nova base de dades. Si ja teniu una base de dades, feu clic a aquesta opció per crear la carpeta, a continuació, posar el seu arxiu dins la carpeta (des del seu PC) i llavors seleccioni aquesta opció nou per obrir l\'arxiu.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH Transferència de fitxer)</string>
<string name="filestoragename_content">Selector d\'arxiu de sistema</string>
<string name="filestorage_setup_title">Inicialització d\'accés a arxiu</string>

View File

@ -425,7 +425,7 @@
<string name="filestoragename_dropboxKP2A">Dropbox (KP2A složka)</string>
<string name="filestoragehelp_dropboxKP2A">Pokud nechcete, aby měl KP2A plný přístup k vašemu Dropbox účtu, může vybrat tuto možnost. Bude vyžadován pouze přístup ke složce Apps/Keepass2Android. Toto je vhodné zejména při vytváření nové databáze. Pokud již máte databázi, zvolte na tuto možnost pro vytvoření složky, poté umístěte soubor (z PC) do této složky a zvolte tuto možnost znovu pro otevření souboru.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH přenos souborů)</string>
<string name="filestoragename_content">Výběr systému souborů</string>
<string name="filestorage_setup_title">Inicializace přístupu k souboru</string>

View File

@ -423,7 +423,7 @@ Der Android Robot wird genutzt und wurde modifiziert basierend auf Arbeiten, die
<string name="filestoragename_dropboxKP2A">Dropbox (KP2A-Ordner)</string>
<string name="filestoragehelp_dropboxKP2A">Wenn du Keepass2Android nicht den Zugriff auf die gesamte Dropbox erlauben möchtest, kannst du diese Option wählen. Dann musst du nur Zugriff auf den Ordner Apps/Keepass2Android gewähren. Das ist besonders sinnvoll, wenn du eine neue Datenbank anlegst. Wenn du schon eine Datenbank hast, kannst du diese Option wählen um den Ordner anzulegen, und dann die Datei (vom PC aus) in den neuen Ordner kopieren. Wähle die Option dann nochmal zum Laden der Datei.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH File Transfer)</string>
<string name="filestoragename_content">Android-Dateibrowser</string>
<string name="filestorage_setup_title">Dateizugriff initialisieren</string>

View File

@ -424,7 +424,7 @@ mediante la autenticación de huellas dactilares. Esto permite desbloquear la ba
<string name="filestoragename_dropboxKP2A">Dropbox (carpeta KP2A)</string>
<string name="filestoragehelp_dropboxKP2A">Si no quieres que KP2A acceda a todo tu contenido en Dropbox, selecciona esta opción. Solicitará acceso sólo a la carpeta Apps/Keepass2Android. Esta opción esta especialmente pensada para cuándo se crea una nueva base de datos. Si tienes una base de datos pre-existente, haz click en esta opción para crear la carpeta. Luego mueve el archivo hasta esta carpeta (desde tu computador) y finalmente selecciona esta opción nuevamente para abrir el archivo.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH transferencia de archivos)</string>
<string name="filestoragename_content">Selector de archivo del sistema</string>
<string name="filestorage_setup_title">Inicialización de acceso de archivo</string>

View File

@ -425,7 +425,7 @@ Mahdollistaa tietokannan avauksen sormenjälkitunnistautumista käyttämällä.
<string name="filestoragename_dropboxKP2A">Dropbox (KP2A kansio)</string>
<string name="filestoragehelp_dropboxKP2A">Jos et halua antaa KP2A pääsyä koko Dropboxiin, voit valita tämän vaihtoehdon. Se pyytää vain Keepass2Android-kansion käyttöoikeuksia. Tämä on erityisen hyvä kun luodaan uusi tietokanta. Jos sinulla on jo tietokanta, valitsemalla tämän vaihtoehdon voit luoda kansion, Sijoita sen jälkeen tiedosto kansioon (tietokoneesta) ja valitse sitten tämä vaihtoehto uudelleen avaamalla tiedosto.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH-tiedostonsiirto)</string>
<string name="filestoragename_content">Järjestelmän tiedostonvalitsin</string>
<string name="filestorage_setup_title">Tiedoston käytön alustaminen</string>

View File

@ -422,7 +422,7 @@ Cela va stocker votre mot de passe maître sur cet appareil, chiffré avec Andro
<string name="filestoragename_dropboxKP2A">Dropbox (dossier KP2A)</string>
<string name="filestoragehelp_dropboxKP2A">Si vous ne voulez pas donner l\'accès KP2A à votre espace Dropbox complet, vous pouvez sélectionner cette option. Seul l\'accès au dossier Apps/Keepass2Android sera demandé. Ceci est particulièrement adapté lorsque vous créez une nouvelle base de données. Si vous avez déjà une base de données, cliquez sur cette option pour créer le dossier, puis placez votre fichier dans le dossier (à partir de votre PC) et puis sélectionnez à nouveau cette option pour ouvrir le fichier.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH File Transfer)</string>
<string name="filestoragename_content">Sélecteur de fichier système</string>
<string name="filestorage_setup_title">Initialisation de l\'accès aux fichiers</string>

View File

@ -427,7 +427,7 @@ Az adatbázist módosíthatja, a szinkronizálásra később is lesz lehetőség
<string name="filestoragename_dropboxKP2A">Dropbox (KPA2 mappa)</string>
<string name="filestoragehelp_dropboxKP2A">Válassza ezt az opciót, ha nem akarja, hogy a KP2A a teljes Dropbox tárhelyhez hozzáférjen. A KP2A csak az Apps/Keepass2Android könyvtárhoz fog hozzáférést igényelni. Ha már meglévő, de máshol tárolt adatbázist kíván ilyen módon elérni, akkor válassza ezt az opciót a könyvtár létrehozásához, majd helyezze át az adatbázisfájlt a létrehozott könyvtárba (például egy PC-ről), majd válassza még egyszer ezt az opciót a fájl megnyitásához.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH File Transfer)</string>
<string name="filestoragename_content">Alapértelmezett fájlválasztó</string>
<string name="filestorage_setup_title">A fájlhozzáférés inicializálása</string>

View File

@ -422,7 +422,7 @@ Questo memorizzerà la password principale su questo dispositivo, cifrata con il
<string name="filestoragename_dropboxKP2A">Dropbox (cartella KP2A)</string>
<string name="filestoragehelp_dropboxKP2A">Se non vuoi dare a KP2A accesso completo al tuo Dropbox, puoi selezionare questa opzione. Richiederà solo l\'accesso alla cartella Apps/Keepass2Android. Ciò è particolarmente indicato quando si crea un nuovo database. Se hai già un database, fai click su questa opzione per creare la cartella, poi spostaci dentro il file (dal PC), quindi seleziona di nuovo questa opzione per aprire il file.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH File Transfer)</string>
<string name="filestoragename_content">Selettore file di sistema</string>
<string name="filestorage_setup_title">Inizializzazione dell\'accesso al file</string>

View File

@ -425,7 +425,7 @@
<string name="filestoragename_dropboxKP2A">Dropbox (KP2A フォルダー)</string>
<string name="filestoragehelp_dropboxKP2A">Dropbox の全てに KP2A がアクセスできるようにしたくない場合にこのオプションを選択してください。このオプションを選択すると、Apps/Keepass2Android フォルダーだけにアクセスを要求します。これは特に新しいデータベースを作成するときに向いています。既にデータベースがある場合は、このオプションを選択してフォルダーを作成し、その後 (PC から) フォルダー内にファイルを配置し、そのファイルを開く際にもう一度このオプションを選択します。</string>
<string name="filestoragename_gdrive">Google ドライブ</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH ファイル転送)</string>
<string name="filestoragename_content">システム ファイル ピッカー</string>
<string name="filestorage_setup_title">ファイルのアクセスの初期化</string>

View File

@ -355,7 +355,7 @@
<string name="filestoragename_dropboxKP2A">Dropbox (KP2A-mappe)</string>
<string name="filestoragehelp_dropboxKP2A">Hvis du ikke vil gi KP2A tilgang til hele Dropbox-mappen din, kan du velge dette alternativet. KP2A vil da bare spørre om tilgang til mappen Apps/Keepass2Android. Dette er spesielt egnet når du oppretter en ny database. Hvis du allerede har en database, trykk på dette alternativet for å opprette mappen, for deretter å plassere filen i mappen (fra en PC) og velge dette alternativet igjen for å åpne filen.</string>
<string name="filestoragename_gdrive">Google Disk</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH File Transfer)</string>
<string name="master_password">Hovedpassord</string>
<string name="help_master_password">Databasen din er kryptert med passordet du angir her. Velg et sterkt passord for å sikre databasen! Tips: Lag en setning eller to og bruk de første bokstavene til ordene som et passord. Inkluder skilletegn.</string>

View File

@ -422,7 +422,7 @@ Dit zal uw hoofdwachtwoord op dit apparaat opslaan. Het wordt versleuteld door d
<string name="filestoragename_dropboxKP2A">Dropbox (KP2A map)</string>
<string name="filestoragehelp_dropboxKP2A">Als u KP2A volledige toegang tot dropbox wilt geven, kiest u deze optie. Het zal alleen toegang vragen tot de map Apps/Keepass2Android. Dit is met name geschikt bij het maken van een nieuwe database. Als u al een database heeft, gebruik deze optie om de map te maken, plaats daarna het bestand in de map (vanaf uw PC) en kies deze optie opnieuw om het bestand te openen.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH File Transfer)</string>
<string name="filestoragename_content">Systeem bestand kiezer</string>
<string name="filestorage_setup_title">Bestandstoegang initaliseren</string>

View File

@ -424,7 +424,7 @@ To zachowa twoje hasła główne na tym urządzeniu.
<string name="filestoragename_dropboxKP2A">Dropbox (folder KP2A)</string>
<string name="filestoragehelp_dropboxKP2A">Jeżeli nie chcesz dać KP2A pełnego dostępu do wszystkich folderów Dropbox, możesz wybrać tę opcję. Aplikacja zażąda dostępu jedynie do folderu Aplikacje/Keepass2Android. Jest to szczególnie przydatne podczas tworzenia nowej bazy danych. Jeżeli już posiadasz bazę danych, kliknij w tę opcję aby utworzyć folder, następnie umieść swój plik w folderze (ze swojego PC) i wybierz tę opcję ponownie aby otworzyć plik.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (transfer plików przez SSH)</string>
<string name="filestoragename_content">Systemowa przeglądarka plików</string>
<string name="filestorage_setup_title">Inicjowanie dostępu do pliku</string>

View File

@ -424,7 +424,7 @@
<string name="filestoragename_dropboxKP2A">Dropbox (pasta KP2A)</string>
<string name="filestoragehelp_dropboxKP2A">Se você não quiser dar acesso KP2A para o seu Dropbox completo, você pode selecionar esta opção. Ele irá solicitar somente acesso para a pasta Apps/Keepass2Android. Isto é especialmente adequado ao criar um novo banco de dados. Se você já tiver um banco de dados, clique nesta opção para criar a pasta, em seguida, colocar o arquivo dentro da pasta (a partir de seu PC) e em seguida, selecione esta opção novamente para abrir o arquivo.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH transferência de arquivos)</string>
<string name="filestoragename_content">Seletor de arquivo de sistema</string>
<string name="filestorage_setup_title">Inicialização do arquivo de acesso</string>

View File

@ -334,7 +334,7 @@ Muito útil se existirem muitos resultados iguais.</string>
<string name="filestoragename_http">HTTP (WebDav)</string>
<string name="filestoragename_dropbox">Dropbox</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (transferência de ficheiros por SSH)</string>
<string name="database_location">Localização da base de dados</string>
<string name="button_change_location">Alterar o local</string>

View File

@ -402,7 +402,7 @@
<string name="filestoragename_dropboxKP2A">Dropbox (folder KP2A)</string>
<string name="filestoragehelp_dropboxKP2A">Dacă nu doriți să oferiți KP2A acces la tot Dropbox-ul, poți selecta această opțiune. Aceasta va solicita acces doar la folderul Apps/Keepass2Android. Acest lucru este ideal când creați o bază de date nouă. Dacă ai deja o bază de date, apasă această opțiune pentru a crea folderul, puneți baza de date în folder (de pe PC) apoi selectați opțiunea aceasta din nou pentru a deschide fișierul.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH File Transfer)</string>
<string name="filestoragename_content">Selector de fisiere sistem</string>
<string name="filestorage_setup_title">Iniţializare acces fişier</string>

View File

@ -425,7 +425,7 @@
<string name="filestoragename_dropboxKP2A">Dropbox (папка KP2A)</string>
<string name="filestoragehelp_dropboxKP2A">Если Вы не хотите предоставлять полный доступ к Dropbox, то можете выбрать эту опцию. Будет запрошен доступ только к папке Apps/Keepass2Android. Это особенно удобно при создании нового файла. Если у вас уже есть файл с данными, выберите этот параметр, чтобы создать папку. После скопируйте базу в папку (с компьютера) и повторно выберите эту опцию для открытия файла.</string>
<string name="filestoragename_gdrive">Диск Google</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH передача файлов)</string>
<string name="filestoragename_content">Системный выбор файла</string>
<string name="filestorage_setup_title">Инициализация доступа к файлу</string>

View File

@ -425,7 +425,7 @@
<string name="filestoragename_dropboxKP2A">Dropbox (priečinok KP2A)</string>
<string name="filestoragehelp_dropboxKP2A">Túto možnosť si môžete vybrať, ak nechcete, aby mal KP2A úplný prístup k úložisku Dropbox. Bude sa vyžadovať iba prístup k priečinku Apps/Keepass2Android. Táto možnosť je vhodná pri vytváraní novej databázy. Ak už máte nejakú databázu, kliknite na túto možnosť pre vytvorenie nového priečinka, potom vložte súbor do priečinka (z PC) a potom znovu vyberte túto možnosť pre otvorenie súboru.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH File Transfer)</string>
<string name="filestoragename_content">Systémový prehliadač súborov</string>
<string name="filestorage_setup_title">Inicializácia prístupu k súboru</string>

View File

@ -425,7 +425,7 @@
<string name="filestoragename_dropboxKP2A">Dropbox (mapa KP2A)</string>
<string name="filestoragehelp_dropboxKP2A">Če dostopa KP2A ne želite dati celemu Dropboxu, lahko izberete to možnost. Zahtevala bo samo dostop do mape Apps/Keepass2Android. To je posebej primerno ob ustvarjanju nove podatkovne zbirke. Če jo že imate, kliknite na to možnost, da ustvarite mapo, v njo vstavite svojo datoteko (iz računalnika) in ponovno izberete to možnost, da datoteko odprete.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (prenos datotek SSH)</string>
<string name="filestoragename_content">Sistemski izbirnik datotek</string>
<string name="filestorage_setup_title">Začenjanje dostopa do datoteke</string>

View File

@ -238,7 +238,7 @@
<string name="filestoragename_https">HTTPS (WebDav)</string>
<string name="filestoragename_dropbox">Dropbox</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH File Transfer)</string>
<string name="database_location">Databasplacering</string>
<string name="button_change_location">Ändra plats</string>

View File

@ -415,7 +415,7 @@
<string name="filestoragename_dropboxKP2A">Dropbox(KP2A Klasörü)</string>
<string name="filestoragehelp_dropboxKP2A">Dropbox heabınıza tam erişim vermek istemiyorsanız, bu seçeneği seçebilirsiniz. Keepass2Android sadece klasör erişimi isteyecek. Özellikle yeni bir veritabanı oluştururken bu uygundur. Bir veritabanınız varsa, klasör oluşturmak için bu seçeneği seçin ve dosyanızı oluşan klasöre taşıyın (bilgisayardan). Dosyayı açmak için bu seçeneği tekrar seçin.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH dosya aktarımı)</string>
<string name="filestoragename_content">Sistem dosyası seçicisi</string>
<string name="filestorage_setup_title">Dosya erişimi başlatma</string>

View File

@ -425,7 +425,7 @@
<string name="filestoragename_dropboxKP2A">Dropbox (папка KP2A)</string>
<string name="filestoragehelp_dropboxKP2A">Якщо ви не бажаєте надати KP2A до всього вашого Dropbox, ви можете вибрати цю опцію. Вона запитає доступ лише до каталогу Apps/Keepass2Android. Це особливо зручно при створенні нового файлу. Якщо ви вже маєте файл з даними, виберіть цю опцію для створення каталогу, після цього покладіть свій файл до цього каталогу (з комп\'ютеру) та виберыть цю опцію знову для відкриття файлу.</string>
<string name="filestoragename_gdrive">Диск Google</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH File Transfer)</string>
<string name="filestoragename_content">Системний вибір файлу</string>
<string name="filestorage_setup_title">Ініціалізація доступу до файлу</string>

View File

@ -360,7 +360,7 @@
<string name="filestoragename_dropboxKP2A">Dropbox (thư mục KP2A)</string>
<string name="filestoragehelp_dropboxKP2A">Nếu bạn không muốn cấp cho KP2A quyền truy cập đầy đủ vô Dropbox, bạn có thể chọn tùy chọn này. Nó sẽ chỉ yêu cầu quyền truy cập vô thư mục Apps/Keepass2Android. Điều này đặc biệt thích hợp khi tạo cơ sở dữ liệu mới. Nếu bạn đã có một cơ sở dữ liệu, hãy nhấp vào tùy chọn này để tạo thư mục, sau đó đặt tập tin của bạn bên trong thư mục (từ máy tính của bạn) và sau đó chọn tùy chọn này một lần nữa để mở tập tin.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (bộ chuyển tập tin SSH)</string>
<string name="filestorage_setup_title">Khởi tạo truy cập tập tin</string>
<string name="database_location">Vị trí cơ sở dữ liệu</string>

View File

@ -423,7 +423,7 @@
<string name="filestoragename_dropboxKP2A">DropboxKP2A 文件夹)</string>
<string name="filestoragehelp_dropboxKP2A">如果你不想让 KP2A 访问整个 Dropbox您可以选中此选项。它将只有访问 应用/Keepass2Android 文件夹的权限。特别适合创建一个新的数据库。如果您已经有一个数据库,点击此选项将创建该新文件夹,然后将你在电脑上的数据库文件放在此文件夹内,然后再选该选项,并以打开该文件。</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTPSSH 文件传输)</string>
<string name="filestoragename_content">系统文件选择器</string>
<string name="filestorage_setup_title">初始化文件访问</string>

View File

@ -387,7 +387,7 @@
<string name="filestoragename_dropboxKP2A">Dropbox (KP2A 資料夾)</string>
<string name="filestoragehelp_dropboxKP2A">如果你不想要給 KP2A 你完整的 Dropbox 訪問權限,您可以選擇此選項。它將請求只訪問應用程式/Keepass2Android 資料夾。這特別適合創建新資料庫時。如果你已經有一個資料庫,請按一下此選項可創建該資料夾,然後 (從您的 PC) 將檔放在資料夾的內部,然後選擇此選項用,再打開檔案。</string>
<string name="filestoragename_gdrive">Google 雲端硬碟</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH 檔案傳輸)</string>
<string name="filestoragename_content">系統檔選擇器</string>
<string name="filestorage_setup_title">檔案存取權限初始化</string>

View File

@ -471,12 +471,18 @@
<string name="ok_donate">Tell me more!</string>
<string name="no_thanks">No, I don\'t like it that much</string>
<string name="hint_sftp_host">host (ex: 192.168.0.1)</string>
<string name="enter_http_login_title">Enter WebDav login data:</string>
<string name="hint_http_url">URL of folder or file (ex: mycloud.me.com/webdav/)</string>
<string name="hint_sftp_host">host (ex: 192.168.0.1)</string>
<string name="hint_sftp_port">port</string>
<string name="initial_directory">Initial directory (optional):</string>
<string name="enter_sftp_login_title">Enter SFTP login data:</string>
<string name="select_storage_type">Select the storage type:</string>
<string name="enter_ftp_login_title">Enter FTP login data:</string>
<string name="select_storage_type">Select the storage type:</string>
<string name="filestoragename_file">Local file</string>
@ -489,8 +495,8 @@
<string name="filestoragename_dropboxKP2A">Dropbox (KP2A folder)</string>
<string name="filestoragehelp_dropboxKP2A">If you do not want to give KP2A access to your full Dropbox, you may select this option. It will request only access to the folder Apps/Keepass2Android. This is especially suited when creating a new database. If you already have a database, click this option to create the folder, then place your file inside the folder (from your PC) and then select this option again for opening the file.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH File Transfer)</string>
<string name="filestoragename_onedrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH File Transfer)</string>
<string name="filestoragename_content">System file picker</string>
<string name="filestorage_setup_title">File access initialization</string>

View File

@ -101,6 +101,10 @@ namespace keepass2android
{
IocSelected(ioc,browseRequestCode);
};
fileSelectHelper.OnCancel += (sender, args) =>
{
ReturnCancel();
};
App.Kp2a.GetFileStorage(protocolId).StartSelectFile(new FileStorageSetupInitiatorActivity(this,
OnActivityResult,

View File

@ -38,6 +38,8 @@ using TwofishCipher;
using Keepass2android.Pluginsdk;
using keepass2android.Io;
using keepass2android.addons.OtpKeyProv;
using Keepass2android.Javafilestorage;
using GoogleDriveFileStorage = keepass2android.Io.GoogleDriveFileStorage;
namespace keepass2android
{
@ -509,9 +511,10 @@ namespace keepass2android
new DropboxFileStorage(Application.Context, this),
new DropboxAppFolderFileStorage(Application.Context, this),
new GoogleDriveFileStorage(Application.Context, this),
new SkyDriveFileStorage(Application.Context, this),
new OneDriveFileStorage(Application.Context, this),
new SftpFileStorage(this),
new NetFtpFileStorage(Application.Context, this),
new WebDavFileStorage(this),
#endif
#endif
new LocalFileStorage(this)
@ -530,24 +533,21 @@ namespace keepass2android
});
}
public bool AlwaysFailOnValidationError()
{
return true;
}
public bool OnValidationError()
{
return false;
}
public RemoteCertificateValidationCallback CertificateValidationCallback
{
get
{
var prefs = PreferenceManager.GetDefaultSharedPreferences(Application.Context);
ValidationMode validationMode = ValidationMode.Warn;
string strValMode = prefs.GetString(Application.Context.Resources.GetString(Resource.String.AcceptAllServerCertificates_key),
Application.Context.Resources.GetString(Resource.String.AcceptAllServerCertificates_default));
if (strValMode == "IGNORE")
validationMode = ValidationMode.Ignore;
else if (strValMode == "ERROR")
validationMode = ValidationMode.Error;
;
switch (validationMode)
switch (GetValidationMode())
{
case ValidationMode.Ignore:
return (sender, certificate, chain, errors) => true;
@ -555,11 +555,7 @@ namespace keepass2android
return (sender, certificate, chain, errors) =>
{
if (errors != SslPolicyErrors.None)
ShowToast(Application.Context.GetString(Resource.String.CertificateWarning,
new Java.Lang.Object[]
{
errors.ToString()
}));
ShowValidationWarning(errors.ToString());
return true;
};
@ -579,6 +575,22 @@ namespace keepass2android
}
private ValidationMode GetValidationMode()
{
var prefs = PreferenceManager.GetDefaultSharedPreferences(Application.Context);
ValidationMode validationMode = ValidationMode.Warn;
string strValMode = prefs.GetString(Application.Context.Resources.GetString(Resource.String.AcceptAllServerCertificates_key),
Application.Context.Resources.GetString(Resource.String.AcceptAllServerCertificates_default));
if (strValMode == "IGNORE")
validationMode = ValidationMode.Ignore;
else if (strValMode == "ERROR")
validationMode = ValidationMode.Error;
return validationMode;
}
public bool CheckForDuplicateUuids
{
get
@ -588,6 +600,49 @@ namespace keepass2android
}
}
public ICertificateErrorHandler CertificateErrorHandler
{
get { return new CertificateErrorHandlerImpl(this); }
}
public class CertificateErrorHandlerImpl : Java.Lang.Object, Keepass2android.Javafilestorage.ICertificateErrorHandler
{
private readonly Kp2aApp _app;
public CertificateErrorHandlerImpl(Kp2aApp app)
{
_app = app;
}
public bool AlwaysFailOnValidationError()
{
return _app.GetValidationMode() == ValidationMode.Error;
}
public bool OnValidationError(string errorMessage)
{
switch (_app.GetValidationMode())
{
case ValidationMode.Ignore:
return true;
case ValidationMode.Warn:
_app.ShowValidationWarning(errorMessage);
return true;
case ValidationMode.Error:
return false;
default:
throw new Exception("Unexpected Validation mode!");
}
}
}
private void ShowValidationWarning(string error)
{
ShowToast(Application.Context.GetString(Resource.String.CertificateWarning, error));
}
public enum ValidationMode
{

View File

@ -38,7 +38,12 @@
<EmbedAssembliesIntoApk>False</EmbedAssembliesIntoApk>
<Debugger>Xamarin</Debugger>
<DevInstrumentationEnabled>True</DevInstrumentationEnabled>
<AndroidSupportedAbis>armeabi;armeabi-v7a;x86</AndroidSupportedAbis>
<AndroidSupportedAbis>armeabi,armeabi-v7a,x86</AndroidSupportedAbis>
<AndroidUseSharedRuntime>True</AndroidUseSharedRuntime>
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
<BundleAssemblies>False</BundleAssemblies>
<AndroidCreatePackagePerAbi>False</AndroidCreatePackagePerAbi>
<AndroidEnableMultiDex>False</AndroidEnableMultiDex>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>full</DebugType>
@ -294,6 +299,9 @@
<AndroidResource Include="Resources\layout\fingerprint_setup.xml">
<SubType>Designer</SubType>
</AndroidResource>
<AndroidResource Include="Resources\layout\httpcredentials.axml">
<SubType>Designer</SubType>
</AndroidResource>
<None Include="settings\RoundsPreference %28Kopie%29.cs">
<Visible>False</Visible>
</None>
@ -424,7 +432,7 @@
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_https.png" />
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_owncloud.png" />
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_sftp.png" />
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_skydrive.png" />
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_onedrive.png" />
<AndroidResource Include="Resources\drawable-mdpi\ic00.png" />
<AndroidResource Include="Resources\drawable-mdpi\ic01.png" />
<AndroidResource Include="Resources\drawable-mdpi\ic02.png" />
@ -702,7 +710,9 @@
</AndroidResource>
<AndroidResource Include="Resources\values-sr\strings.xml" />
<AndroidResource Include="Resources\values-sv\strings.xml" />
<AndroidResource Include="Resources\values-tr\strings.xml" />
<AndroidResource Include="Resources\values-tr\strings.xml">
<SubType>Designer</SubType>
</AndroidResource>
<AndroidResource Include="Resources\values-vi\strings.xml" />
<AndroidResource Include="Resources\values-de\strings.xml">
<SubType>Designer</SubType>
@ -722,7 +732,9 @@
<AndroidResource Include="Resources\values-ru\strings.xml" />
<AndroidResource Include="Resources\values-sk\strings.xml" />
<AndroidResource Include="Resources\values-uk\strings.xml" />
<AndroidResource Include="Resources\values-zh-rCN\strings.xml" />
<AndroidResource Include="Resources\values-zh-rCN\strings.xml">
<SubType>Designer</SubType>
</AndroidResource>
<AndroidResource Include="Resources\values-zh-rTW\strings.xml" />
<AndroidResource Include="Resources\layout\InViewButton.xml">
<SubType>Designer</SubType>
@ -1103,7 +1115,7 @@
<AndroidResource Include="Resources\drawable-xhdpi\ic_storage_sftp.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\ic_storage_skydrive.png" />
<AndroidResource Include="Resources\drawable-xhdpi\ic_storage_onedrive.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\ic00.png" />