Merge branch 'master' of C:\ph\keepass2android

Conflicts:
	src/java/KP2ASoftkeyboard_AS/.gradle/2.2.1/taskArtifacts/fileHashes.bin
	src/java/KP2ASoftkeyboard_AS/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin
	src/java/KP2ASoftkeyboard_AS/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin
This commit is contained in:
Philipp Crocoll
2017-04-11 02:22:54 +02:00
44 changed files with 2360 additions and 102 deletions

View File

@@ -9,7 +9,9 @@ using KeePassLib;
using KeePassLib.Keys;
using KeePassLib.Serialization;
using keepass2android.Io;
#if !NoNet
using Keepass2android.Javafilestorage;
#endif
namespace keepass2android
{
@@ -107,6 +109,8 @@ namespace keepass2android
bool CheckForDuplicateUuids { get; }
#if !NoNet
ICertificateErrorHandler CertificateErrorHandler { get; }
#endif
}
}

View File

@@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Security;
using Android;
using Android.App;
@@ -13,7 +13,7 @@ using Android.OS;
using Java.IO;
using KeePassLib.Serialization;
using KeePassLib.Utility;
using ModernHttpClient;
using File = System.IO.File;
using FileNotFoundException = System.IO.FileNotFoundException;
using IOException = System.IO.IOException;
@@ -416,6 +416,23 @@ namespace keepass2android.Io
}
}
public class LocalFileStorage : BuiltInFileStorage
{
public LocalFileStorage(IKp2aApp app)
: base(app)
{
}
public override IEnumerable<string> SupportedProtocols
{
get
{
yield return "file";
}
}
}
#if !NoNet
public class LegacyFtpStorage : BuiltInFileStorage
{
public LegacyFtpStorage(IKp2aApp app) : base(app)
@@ -426,9 +443,9 @@ namespace keepass2android.Io
{
get
{
#if !NoNet
yield return "ftp";
#endif
}
}
}
@@ -443,27 +460,14 @@ namespace keepass2android.Io
{
get
{
#if !NoNet
yield return "http";
yield return "https";
}
}
}
#endif
}
}
}
public class LocalFileStorage : BuiltInFileStorage
{
public LocalFileStorage(IKp2aApp app) : base(app)
{
}
public override IEnumerable<string> SupportedProtocols
{
get
{
yield return "file";
}
}
}
}

View File

@@ -1,3 +1,4 @@
#if !NoNet
using System;
using System.Collections.Generic;
using System.IO;
@@ -639,4 +640,5 @@ namespace keepass2android.Io
_stream.Close();
}
}
}
}
#endif

View File

@@ -47,23 +47,13 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="ModernHttpClient">
<HintPath>..\Components\modernhttpclient-2.4.2\lib\android\ModernHttpClient.dll</HintPath>
</Reference>
<Reference Include="Mono.Android" />
<Reference Include="Mono.Security" />
<Reference Include="mscorlib" />
<Reference Include="OkHttp">
<HintPath>..\Components\modernhttpclient-2.4.2\lib\android\OkHttp.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Xml" />
<Reference Include="Xamarin.Insights">
<HintPath>..\packages\Xamarin.Insights.1.11.3\lib\MonoAndroid10\Xamarin.Insights.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="database\CheckDatabaseForChanges.cs" />
@@ -133,10 +123,6 @@
<Compile Include="Utils\Spr\SprEngine.PickChars.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\JavaFileStorageBindings\JavaFileStorageBindings.csproj">
<Project>{48574278-4779-4b3a-a9e4-9cf1bc285d0b}</Project>
<Name>JavaFileStorageBindings</Name>
</ProjectReference>
<ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj">
<Project>{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}</Project>
<Name>KeePassLib2Android</Name>
@@ -145,10 +131,6 @@
<Project>{70D3844A-D9FA-4A64-B205-A84C6A822196}</Project>
<Name>KP2AKdbLibraryBinding</Name>
</ProjectReference>
<ProjectReference Include="..\netftpandroid\System.Net.FtpClient\System.Net.FtpClient.Android.csproj">
<Project>{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}</Project>
<Name>System.Net.FtpClient.Android</Name>
</ProjectReference>
<ProjectReference Include="..\TwofishCipher\TwofishCipher.csproj">
<Project>{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}</Project>
<Name>TwofishCipher</Name>
@@ -157,12 +139,6 @@
<ItemGroup>
<Folder Include="Resources\" />
</ItemGroup>
<ItemGroup>
<XamarinComponentReference Include="modernhttpclient">
<Visible>False</Visible>
<Version>2.4.2</Version>
</XamarinComponentReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.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.

View File

@@ -0,0 +1,8 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures

View File

@@ -0,0 +1 @@
/build

View File

@@ -0,0 +1,32 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion '23.0.2'
defaultConfig {
applicationId "com.crocoapps.javafilestoragetest"
minSdkVersion 21
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
compile project(':JavaFileStorage')
compile project(':android-filechooser')
}
configurations {
compile.exclude group: "org.apache.httpcomponents", module: "httpclient"
}

View File

@@ -0,0 +1,20 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:\Users\Philipp\AppData\Local\Xamarin\Universal\AndroidSDK/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
-dontwarn
-ignorewarnings

View File

@@ -0,0 +1,13 @@
package com.crocoapps.javafilestoragetest;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.crocoapps.javafilestoragetest">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
tools:replace="android:icon"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="keepass2android.kp2afilechooser.StorageFileProvider"
android:authorities="keepass2android.kp2afilechooser.StorageFileProvider"
android:exported="false" />
<provider
android:name="group.pals.android.lib.ui.filechooser.providers.localfile.LocalFileProvider"
android:authorities="com.crocoapps.javafilestoragetest.android-filechooser.localfile"
android:exported="false" />
<provider
android:name="group.pals.android.lib.ui.filechooser.providers.history.HistoryProvider"
android:authorities="com.crocoapps.javafilestoragetest.android-filechooser.history"
android:exported="false" />
<activity
android:name="group.pals.android.lib.ui.filechooser.FileChooserActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:screenOrientation="user"
android:theme="@style/Afc.Theme.Light" />
<activity
android:name="com.crocoapps.javafilestoragetest.FileStorageSetupActivity"
android:label="@string/title_activity_file_storage_setup" >
</activity>
<activity
android:name="com.dropbox.core.android.AuthActivity"
android:configChanges="orientation|keyboard"
android:launchMode="singleTask" >
<intent-filter>
<data android:scheme="db-4ybka4p4a1027n6" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>

View File

@@ -0,0 +1,114 @@
package com.crocoapps.javafilestoragetest;
import keepass2android.javafilestorage.JavaFileStorage;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
public class FileStorageSetupActivity
extends Activity implements JavaFileStorage.FileStorageSetupActivity {
Bundle state = new Bundle();
boolean isRecreated = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_storage_setup);
Log.d("FSSA", "onCreate");
if (savedInstanceState != null)
{
isRecreated = true;
state = (Bundle) savedInstanceState.clone();
Log.d("FSSA", "recreating state");
for (String key: state.keySet())
{
Log.d("FSSA", "state " + key + ":" +state.get(key));
}
}
if (!isRecreated)
{
if (MainActivity.storageToTest == null)
MainActivity.createStorageToTest(this, getApplicationContext(), false);
MainActivity.storageToTest.onCreate(this, savedInstanceState);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putAll(state);
Log.d("FSSA", "storing state");
for (String key: state.keySet())
{
Log.d("FSSA", "state " + key + ":" +state.get(key));
}
}
@Override
protected void onResume() {
super.onResume();
if (MainActivity.storageToTest == null)
{
Log.d("FSSA", "MainActivity.storageToTest==null!");
MainActivity.createStorageToTest(getApplicationContext(), getApplicationContext(), false);
}
else
Log.d("FSSA", "MainActivity.storageToTest is safe!");
MainActivity.storageToTest.onResume(this);
}
@Override
protected void onStart() {
super.onStart();
if (!isRecreated)
MainActivity.storageToTest.onStart(this);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
MainActivity.storageToTest.onActivityResult(this, requestCode, resultCode, data);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.file_storage_setup, menu);
return true;
}
@Override
public String getPath() {
// TODO Auto-generated method stub
return getIntent().getStringExtra(JavaFileStorage.EXTRA_PATH);
}
@Override
public String getProcessName() {
return getIntent().getStringExtra(JavaFileStorage.EXTRA_PROCESS_NAME);
}
@Override
public boolean isForSave() {
return getIntent().getBooleanExtra(JavaFileStorage.EXTRA_IS_FOR_SAVE, false);
}
@Override
public Bundle getState() {
Log.d("FSSA", "returning state");
for (String key: state.keySet())
{
Log.d("FSSA", "state " + key + ":" +state.get(key));
}
return state;
}
}

View File

@@ -0,0 +1,745 @@
package com.crocoapps.javafilestoragetest;
//
//import java.io.IOException;
//import java.util.ArrayList;
//import java.util.List;
//import android.accounts.AccountManager;
//import android.app.Activity;
//import android.content.Intent;
//import android.os.Bundle;
//import android.util.Log;
//import android.widget.Toast;
//
//import com.google.api.client.extensions.android.http.AndroidHttp;
//import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
//import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
//import com.google.api.client.http.ByteArrayContent;
//import com.google.api.client.json.gson.GsonFactory;
//import com.google.api.services.drive.Drive;
//import com.google.api.services.drive.DriveScopes;
//import com.google.api.services.drive.model.File;
//import com.google.api.services.drive.model.FileList;
//
//public class MainActivity extends Activity {
// static final int REQUEST_ACCOUNT_PICKER = 1;
// static final int REQUEST_AUTHORIZATION = 2;
// static final int CAPTURE_IMAGE = 3;
//
// private static Drive service;
//
//
// @Override
// public void onCreate(Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
//
// List<String> scopes = new ArrayList<String>();
// scopes.add(DriveScopes.DRIVE);
// GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(this, scopes);
// startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
// }
//
// @Override
// protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
// switch (requestCode) {
// case REQUEST_ACCOUNT_PICKER:
// if (resultCode == RESULT_OK && data != null && data.getExtras() != null) {
// String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
// if (accountName != null) {
// List<String> scopes = new ArrayList<String>();
// scopes.add(DriveScopes.DRIVE);
// GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(this, scopes);
// credential.setSelectedAccountName(accountName);
// service = getDriveService(credential);
// saveFileToDrive();
// }
// }
// break;
// case REQUEST_AUTHORIZATION:
// if (resultCode == Activity.RESULT_OK) {
// saveFileToDrive();
// } else {
// List<String> scopes = new ArrayList<String>();
// scopes.add(DriveScopes.DRIVE);
// GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(this, scopes);
// startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
// }
// break;
// }
// }
// private void saveFileToDrive() {
// Thread t = new Thread(new Runnable() {
// @Override
// public void run() {
// try {
// // File's binary content
// ByteArrayContent mediaContent = new ByteArrayContent("text/plain","abcnrt".getBytes());
//
// // File's metadata.
// File body = new File();
// body.setTitle("sometext.txt");
// body.setMimeType("text/plain");
//
// listFolders("root", 0);
//
///* FileList folders=service.files().list().setQ("mimeType='application/vnd.google-apps.folder' and trashed=false and hidden=false").execute();
// for(File fl: folders.getItems()){
// Log.v("JFS"+" fOLDER name:",fl.getTitle());
// }
// *//*
//
//
// File file = service.files().insert(body, mediaContent).execute();
// if (file != null) {
// showToast("File uploaded: " + file.getTitle());
//
// }*/
// } catch (UserRecoverableAuthIOException e) {
// startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
//
// private void listFolders(String id, int level) throws IOException {
// FileList folders=service.files().list().setQ("mimeType='application/vnd.google-apps.folder' and trashed=false and hidden=false and '"+id+"' in parents").execute();
// for(File fl: folders.getItems()){
// String pre = "";
// for (int i=0;i<level;i++)
// pre += "> ";
// Log.v("JFS fOLDER name:",pre+fl.getTitle());
// listFolders(fl.getId(), level+1);
// }
//
// }
// });
// t.start();
// }
//
// private Drive getDriveService(GoogleAccountCredential credential) {
// return new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), credential)
// .build();
// }
//
// public void showToast(final String toast) {
// runOnUiThread(new Runnable() {
// @Override
// public void run() {
// Toast.makeText(getApplicationContext(), toast, Toast.LENGTH_SHORT).show();
// }
// });
// }
//}
import group.pals.android.lib.ui.filechooser.FileChooserActivity;
import group.pals.android.lib.ui.filechooser.providers.BaseFileProviderUtils;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
//import keepass2android.javafilestorage.DropboxCloudRailStorage;
import keepass2android.javafilestorage.DropboxV2Storage;
import keepass2android.javafilestorage.ICertificateErrorHandler;
import keepass2android.javafilestorage.JavaFileStorage;
import keepass2android.javafilestorage.JavaFileStorage.FileEntry;
import keepass2android.javafilestorage.OneDriveStorage;
import keepass2android.javafilestorage.SftpStorage;
import keepass2android.javafilestorage.UserInteractionRequiredException;
import keepass2android.javafilestorage.WebDavStorage;
import keepass2android.kp2afilechooser.StorageFileProvider;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.Toast;
/**
* @author Philipp
*
*/
public class MainActivity extends Activity implements JavaFileStorage.FileStorageSetupInitiatorActivity {
//a little dirty hack: make the file storage available to the whole app
//this is implemented nicer in the real app...
public static JavaFileStorage storageToTest;
class PerformTestTask extends AsyncTask<Object, Void, Void>
{
String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
@Override
protected Void doInBackground(Object... params) {
try {
String parentPath = (String)params[0];
String testPath = (String)params[1];
JavaFileStorage fs = (JavaFileStorage)params[2];
String path;
try
{
path = fs.createFolder(parentPath, testPath);
}
catch (Exception e)
{
//if exception because folder exists
path = fs.createFilePath(parentPath, testPath);
}
FileEntry e1 = fs.getFileEntry(parentPath);
FileEntry e2 = fs.getFileEntry(path);
boolean receivedFileNotFoundException;
/*
if (e1.displayName == null) throw new Exception("displayName of "+parentPath+" is null!");
if (e2.displayName.equals(testPath) == false) throw new Exception("displayName of "+path+" is "+e2.displayName+"!");
//try to delete the file to prepare the test. if this fails, we ignore it for now
try
{
fs.delete(path);
}
catch (Exception e)
{
e.printStackTrace();
}
Log.d("KP2AJ", "checking if folder "+path+" exists...");
receivedFileNotFoundException = false;
try
{
fs.listFiles(path);
}
catch (java.io.FileNotFoundException ex)
{
receivedFileNotFoundException = true;
}
if (!receivedFileNotFoundException)
throw new Exception("Either listFiles() didn't throw when listing an unexisting path or the path "+path+" already exists. Please make sure it doesn't!");
Log.d("KP2AJ", "creating folder "+path);
path = fs.createFolder(parentPath, testPath);
Log.d("KP2AJ", "creating folder returned without exception. Now list its contents.");
*/
List<FileEntry> filesInEmptyDir = fs.listFiles(path);
if (!filesInEmptyDir.isEmpty())
{
for (FileEntry fe: filesInEmptyDir)
Log.d("KP2AJ", fe.path+", "+fe.displayName);
throw new Exception("Received non-empty list with "+filesInEmptyDir.size()+" entries after creating directory!");
}
Log.d("KP2AJ", "Ok. Write a file to the folder:");
String textToUpload = "abcdefg";
String filename = fs.createFilePath(path, "file.txt");
/*if (!path.endsWith("/"))
path += "/";
String filename = path+"file.text";*/
fs.uploadFile(filename,textToUpload.getBytes(),true);
Log.d("KP2AJ", "Ok. Read contents:");
InputStream s = fs.openFileForRead(filename);
String receivedText = convertStreamToString(s);
if (!receivedText.equals(textToUpload))
throw new Exception("Received unexpected contents: "+receivedText+" vs. " + textToUpload);
Log.d("KP2AJ", "Ok. Query version:");
String version0 = fs.getCurrentFileVersionFast(filename);
Log.d("KP2AJ", "Ok. Get FileEntry:");
FileEntry e = fs.getFileEntry(filename);
if (!e.path.toLowerCase().equals(filename.toLowerCase()) || e.isDirectory)
throw new Exception("invalid file entry record!");
if (version0 == null)
Log.d("KP2AJ", "WARNING: getCurrentFileVersionFast shouldn't return null");
Log.d("KP2AJ", "Ok. Modify the file:");
//sleep a second to ensure we have some time between the two modifications (if this is contained in the file version, they should be different)
Thread.sleep(1000);
String newTextToUpload = "xyz123";
fs.uploadFile(filename,newTextToUpload.getBytes(),true);
Log.d("KP2AJ", "Ok. Read contents:");
s = fs.openFileForRead(filename);
receivedText = convertStreamToString(s);
if (!receivedText.equals(newTextToUpload))
throw new Exception("Received unexpected contents: "+receivedText+" vs. " + newTextToUpload);
String version1 = fs.getCurrentFileVersionFast(filename);
if (version0 != null)
{
if (version0.equals(version1))
throw new Exception("getCurrentFileVersionFast returned same version string "+version0+" after modification!");
}
if (fs.checkForFileChangeFast(filename, version0) == false)
{
//no failure because it's allowed to return false even if there was a change - but it's not good, so warn:
Log.d("KP2AJ", "WARNING! checkForFileChangeFast returned false even though the files were modified!");
}
Log.d("KP2AJ", "Try to open an unexisting file:");
receivedFileNotFoundException = false;
try
{
fs.openFileForRead(path+"/unexisting.txt");
}
catch (java.io.FileNotFoundException ex)
{
receivedFileNotFoundException = true;
}
if (!receivedFileNotFoundException)
throw new Exception("Didn't received file not found exception for unexisting file!");
Log.d("KP2AJ", "Create some more folders and files: ");
String subfolderPath = fs.createFolder(path,"subfolder");
String anotherFileInSubfolderPath = fs.createFilePath(subfolderPath, "anotherfile.txt");
String anotherFilePath = fs.createFilePath(path, "anotherfile.txt");
fs.uploadFile(anotherFileInSubfolderPath, textToUpload.getBytes(), true);
fs.uploadFile(anotherFilePath, textToUpload.getBytes(), false); // try non-transacted as well
Log.d("KP2AJ", "List files:");
List<FileEntry> fileList = fs.listFiles(path);
checkFileList(path, fileList, true, true);
Log.d("KP2AJ", "getFilename:");
testGetFilename(fileList, fs);
Log.d("KP2AJ", "Delete a file");
fs.delete(filename);
Log.d("KP2AJ", "List files again to check if deleting the file was successful:");
fileList = fs.listFiles(path);
checkFileList(path, fileList, false, true); //second param indicates the file must be gone
Log.d("KP2AJ", "Delete a folder recursive");
fs.delete(subfolderPath);
Log.d("KP2AJ", "List files again to check if deleting the folder was successful:");
fileList = fs.listFiles(path);
checkFileList(path, fileList, false, false); //third param indicates the folder must be gone
Log.d("KP2AJ", "Delete the main test folder");
fs.delete(path);
Log.d("KP2AJ", "ALL TESTS OK!");
} catch (Exception e) {
Log.d("KP2AJ", "Test failed with exception!");
Log.d("KP2AJ",e.toString());
e.printStackTrace();
}
return null;
}
private void testGetFilename(List<FileEntry> fileList,
JavaFileStorage fs) throws Exception {
for (FileEntry e: fileList)
{
String fileName = fs.getFilename(e.path);
if (!fileName.equals(e.displayName))
{
Log.e("KP2AJ", "Received "+fileName+" for " + e.path + " but expected " + e.displayName);
throw new Exception("error!");
}
}
}
private void checkFileList(String basepath, List<FileEntry> fileList, boolean expectDeletableFile, boolean expectDeletableFolder) throws Exception {
FileEntry expectedFile = new FileEntry();
expectedFile.canRead = expectedFile.canWrite = true;
expectedFile.isDirectory = false;
expectedFile.displayName = "anotherfile.txt";
expectedFile.sizeInBytes = 7; //("abcdefg")
//lastModifiedTime is not known
checkFileIsContained(fileList, expectedFile);
int expectedSize = 1;
if (expectDeletableFile)
{
expectedFile.displayName = "file.txt";
expectedFile.sizeInBytes = 6; //"xyz123"
checkFileIsContained(fileList, expectedFile);
expectedSize++;
}
if (expectDeletableFolder)
{
FileEntry expectedDir = new FileEntry();
expectedDir.canRead = expectedFile.canWrite = true;
expectedDir.isDirectory = true;
expectedDir.displayName = "subfolder";
checkFileIsContained(fileList, expectedDir);
expectedSize++;
}
if (fileList.size() != expectedSize)
throw new Exception("Unexpected number of entries in fileList: " + fileList.size());
}
private void checkFileIsContained(List<FileEntry> fileList,
FileEntry file) throws Exception {
for (FileEntry e: fileList)
{
if ((e.canRead == file.canRead)
&& (e.canWrite == file.canWrite)
&& (e.isDirectory == file.isDirectory)
&& (e.displayName.equals(file.displayName))
&& (e.sizeInBytes == file.sizeInBytes ))
return;
}
throw new Exception("didn't find file " + file.path + " in file list!");
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (storageToTest == null)
{
createStorageToTest(this, getApplicationContext(), false);
}
findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
storageToTest.startSelectFile(MainActivity.this, false, 1);
}
});
findViewById(R.id.button_test_filechooser).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
storageToTest.startSelectFile(MainActivity.this, false, 2);
}
});
findViewById(R.id.button_test_filechooser_saveas).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
storageToTest.startSelectFile(MainActivity.this, true, 3);
}
});
findViewById(R.id.button_test_preparefileusage).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
final String path = PreferenceManager.getDefaultSharedPreferences(MainActivity.this).getString("selectedPath", "");
if (path.equals(""))
{
Toast.makeText(MainActivity.this, "select path with file chooser first", Toast.LENGTH_LONG).show();
return;
}
new AsyncTask<Object, Object, Object>() {
@Override
protected Object doInBackground(Object... params) {
try
{
createStorageToTest(MainActivity.this, MainActivity.this.getApplicationContext(), false).prepareFileUsage(MainActivity.this, path);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "prepare ok: " + path, Toast.LENGTH_LONG).show();
}
});
}
catch (UserInteractionRequiredException e)
{
final UserInteractionRequiredException e2 = e;
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "this requires user interaction! "+e2.getClass().getName()+ " "+e2.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
catch (Throwable t)
{
final Throwable t2 = t;
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, t2.getClass().getName()+": "+ t2.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
return null;
}
}.execute();
}
});
}
static JavaFileStorage createStorageToTest(Context ctx, Context appContext, boolean simulateRestart) {
//storageToTest = new SftpStorage();
//storageToTest = new SkyDriveFileStorage("000000004010C234", appContext);
storageToTest = new OneDriveStorage(appContext, "000000004010C234");
//storageToTest = new GoogleDriveFileStorage();
/*storageToTest = new WebDavStorage(new ICertificateErrorHandler() {
@Override
public boolean onValidationError(String error) {
return false;
}
@Override
public boolean alwaysFailOnValidationError() {
return false;
}
});*/
//storageToTest = new DropboxV2Storage(ctx,"4ybka4p4a1027n6", "1z5lv528un9nre8", !simulateRestart);
//storageToTest = new DropboxFileStorage(ctx,"4ybka4p4a1027n6", "1z5lv528un9nre8", !simulateRestart);
//storageToTest = new DropboxAppFolderFileStorage(ctx,"ax0268uydp1ya57", "3s86datjhkihwyc", true);
return storageToTest;
}
@Override
protected void onResume()
{
super.onResume();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == JavaFileStorage.RESULT_FILECHOOSER_PREPARED)
{
String path = data.getStringExtra(JavaFileStorage.EXTRA_PATH);
onReceivePathForFileSelect(requestCode, path);
}
if ((requestCode == 1) && (resultCode == RESULT_OK))
{
ArrayList<Uri> uris = data
.getParcelableArrayListExtra(FileChooserActivity.EXTRA_RESULTS);
String path = BaseFileProviderUtils.getRealUri(this, uris.get(0)).toString();
PreferenceManager.getDefaultSharedPreferences(this).edit()
.putString("selectedPath", path).commit();
//create a new storage to simulate the case that the file name was saved and is used again after restarting the app:
createStorageToTest(this, getApplicationContext(), true).prepareFileUsage(this, path, 2123, false);
}
if ((requestCode == 2123) && (resultCode == JavaFileStorage.RESULT_FILEUSAGE_PREPARED))
{
Toast.makeText(this, "Successfully prepared file usage!", Toast.LENGTH_LONG).show();
}
if ((requestCode == 2124) && (resultCode == RESULT_OK))
{
ArrayList<Uri> uris = data
.getParcelableArrayListExtra(FileChooserActivity.EXTRA_RESULTS);
String path = BaseFileProviderUtils.getRealUri(this, uris.get(0)).toString();
boolean fileExists = data.getBooleanExtra(FileChooserActivity.EXTRA_RESULT_FILE_EXISTS, false);
Toast.makeText(this, "Selected file path for save: "+path+". File exists: " +fileExists, Toast.LENGTH_LONG).show();
}
}
private void onReceivePathForFileSelect(int requestCode, String path) {
Toast.makeText(this, "requestCode: "+requestCode, Toast.LENGTH_LONG).show();
if (requestCode == 1)
//new PerformTestTask().execute(path,"TestFileStorage<67>", storageToTest); //use an umlaut to see how that works
new PerformTestTask().execute(path,"TestFileStorage", storageToTest);
else
if (requestCode == 2)
{
Intent intent = keepass2android.kp2afilechooser.Kp2aFileChooserBridge.getLaunchFileChooserIntent(this, StorageFileProvider.authority, path);
startActivityForResult(intent, 1);
}
if (requestCode == 3)
{
Intent intent = keepass2android.kp2afilechooser.Kp2aFileChooserBridge.getLaunchFileChooserIntent(this, StorageFileProvider.authority, path);
intent.putExtra("group.pals.android.lib.ui.filechooser.FileChooserActivity.save_dialog", true);
intent.putExtra("group.pals.android.lib.ui.filechooser.FileChooserActivity.default_file_ext", "kdbx");
startActivityForResult(intent, 2124);
}
}
@Override
public void startSelectFileProcess(String path, boolean isForSave,
int requestCode) {
Intent intent = new Intent(this, FileStorageSetupActivity.class);
intent.putExtra(JavaFileStorage.EXTRA_PROCESS_NAME, JavaFileStorage.PROCESS_NAME_SELECTFILE);
intent.putExtra(JavaFileStorage.EXTRA_PATH, path);
startActivityForResult(intent, requestCode);
}
@Override
public void startFileUsageProcess(String path, int requestCode, boolean alwaysReturnSuccess) {
Intent intent = new Intent(this, FileStorageSetupActivity.class);
intent.putExtra(JavaFileStorage.EXTRA_PROCESS_NAME, JavaFileStorage.PROCESS_NAME_FILE_USAGE_SETUP);
intent.putExtra(JavaFileStorage.EXTRA_PATH, path);
startActivityForResult(intent, requestCode);
}
@Override
public void onImmediateResult(int requestCode, int result, Intent intent) {
onActivityResult(requestCode, result, intent);
}
@Override
public Activity getActivity() {
return this;
}
@Override
public void performManualFileSelect(boolean isForSave, final int requestCode,
String protocolId)
{
if (protocolId.equals("sftp"))
{
final View view = getLayoutInflater().inflate(R.layout.sftp_credentials, null);
new AlertDialog.Builder(this)
.setView(view)
.setTitle("Enter SFTP credentials")
.setPositiveButton("OK",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "Hey", Toast.LENGTH_LONG).show();
SftpStorage sftpStorage = (SftpStorage)storageToTest;
try {
EditText etHost = ((EditText)view.findViewById(R.id.sftp_host));
String host = etHost.getText().toString();
EditText etUser = ((EditText)view.findViewById(R.id.sftp_user));
String user = etUser.getText().toString();
EditText etPwd = ((EditText)view.findViewById(R.id.sftp_password));
String pwd = etPwd.getText().toString();
EditText etPort = ((EditText)view.findViewById(R.id.sftp_port));
int port = Integer.parseInt(etPort.getText().toString());
EditText etInitDir = ((EditText)view.findViewById(R.id.sftp_initial_dir));
String initialDir = etInitDir.getText().toString();
onReceivePathForFileSelect(requestCode, sftpStorage.buildFullPath( host, port, initialDir, user, pwd));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
})
.create()
.show();
}
else
{
final View view = getLayoutInflater().inflate(R.layout.webdav_credentials, null);
new AlertDialog.Builder(this)
.setView(view)
.setTitle("Enter WebDAV credentials")
.setPositiveButton("OK",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "Hey", Toast.LENGTH_LONG).show();
WebDavStorage storage = (WebDavStorage)storageToTest;
try {
EditText etHost = ((EditText)view.findViewById(R.id.webdav_host));
String host = etHost.getText().toString();
EditText etUser = ((EditText)view.findViewById(R.id.user));
String user = etUser.getText().toString();
EditText etPwd = ((EditText)view.findViewById(R.id.password));
String pwd = etPwd.getText().toString();
onReceivePathForFileSelect(requestCode, storage.buildFullPath( host, user, pwd));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
})
.create()
.show();
}
}
}

View File

@@ -0,0 +1,88 @@
package keepass2android.kp2afilechooser;
import java.util.List;
import com.crocoapps.javafilestoragetest.MainActivity;
public class StorageFileProvider extends Kp2aFileProvider {
public static String authority = "keepass2android.kp2afilechooser.StorageFileProvider";
@Override
public String getAuthority() {
return authority;
}
@Override
protected FileEntry getFileEntry(String path, StringBuilder errorMessageBuilder) throws Exception {
keepass2android.javafilestorage.JavaFileStorage.FileEntry entry = MainActivity.storageToTest.getFileEntry(path);
keepass2android.kp2afilechooser.FileEntry chooserEntry = convertEntry(entry);
return chooserEntry;
}
private keepass2android.kp2afilechooser.FileEntry convertEntry(
keepass2android.javafilestorage.JavaFileStorage.FileEntry entry) {
keepass2android.kp2afilechooser.FileEntry chooserEntry = new FileEntry();
chooserEntry.canRead = entry.canRead;
chooserEntry.canWrite = entry.canWrite;
chooserEntry.displayName = entry.displayName;
chooserEntry.isDirectory = entry.isDirectory;
chooserEntry.lastModifiedTime = entry.lastModifiedTime;
chooserEntry.path = entry.path;
chooserEntry.sizeInBytes = entry.sizeInBytes;
return chooserEntry;
}
@Override
protected void listFiles(int taskId, String dirName,
boolean showHiddenFiles, int filterMode, int limit,
String positiveRegex, String negativeRegex,
List<keepass2android.kp2afilechooser.FileEntry> results, boolean[] hasMoreFiles) {
List<keepass2android.javafilestorage.JavaFileStorage.FileEntry> entries;
try {
entries = MainActivity.storageToTest.listFiles(dirName);
for (keepass2android.javafilestorage.JavaFileStorage.FileEntry e: entries)
{
keepass2android.kp2afilechooser.FileEntry chooserEntry = convertEntry(e);
results.add(chooserEntry);
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
@Override
protected boolean deletePath(String filename, boolean isRecursive) {
try
{
MainActivity.storageToTest.delete(filename);
return true;
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
}
@Override
protected boolean createDirectory(String dirname, String newDirName) {
try
{
MainActivity.storageToTest.createFolder(dirname, newDirName);
return true;
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
}
}

View File

@@ -0,0 +1,24 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".FileStorageSetupActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Please wait..." />
<ProgressBar
android:id="@+id/fssa_progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_centerInParent="true"
android:indeterminateOnly="true" />
</RelativeLayout>

View File

@@ -0,0 +1,57 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="JavaFileStorage Test App" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_below="@+id/textView1"
android:layout_marginLeft="17dp"
android:text="Run test" />
<Button
android:id="@+id/button_test_filechooser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="17dp"
android:layout_alignLeft="@+id/textView1"
android:layout_below="@+id/button1"
android:text="Test File Chooser" />
<Button
android:id="@+id/button_test_filechooser_saveas"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_below="@+id/button_test_filechooser"
android:layout_marginLeft="17dp"
android:text="Test File Chooser Save As" />
<Button
android:id="@+id/button_test_preparefileusage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_below="@+id/button_test_filechooser_saveas"
android:layout_marginLeft="17dp"
android:text="Test Prepare File Usage" />
</RelativeLayout>

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="12dip"
>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/sftp_host"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:inputType="textNoSuggestions"
android:text=""
android:hint="@string/hint_sftp_host" />
<TextView
android:id="@+id/portsep"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=":" />
<EditText
android:id="@+id/sftp_port"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:inputType="number"
android:text="22"
android:hint="@string/hint_sftp_port" />
</LinearLayout>
<EditText
android:id="@+id/sftp_user"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:text=""
android:hint="@string/hint_username" />
<EditText
android:id="@+id/sftp_password"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:singleLine="true"
android:text=""
android:hint="@string/hint_pass" />
<TextView android:id="@+id/initial_dir"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dip"
android:layout_marginTop="4dip"
android:text="@string/initial_directory" />
<EditText
android:id="@+id/sftp_initial_dir"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="/home/philipp"
/>
</LinearLayout>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="12dip"
>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/webdav_host"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:inputType="textNoSuggestions"
android:text=""
android:hint="Server URL" />
</LinearLayout>
<EditText
android:id="@+id/user"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="Keepass"
android:hint="@string/hint_username" />
<EditText
android:id="@+id/password"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:singleLine="true"
android:text=""
android:hint="@string/hint_pass" />
</LinearLayout>

View File

@@ -0,0 +1,9 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>

View File

@@ -0,0 +1,9 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -0,0 +1,6 @@
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>

View File

@@ -0,0 +1,5 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>

View File

@@ -0,0 +1,529 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<string name="title_activity_file_storage_setup">FileStorageSetupActivity</string>
<string name="about_feedback">Feedback</string>
<string name="about_homepage">Homepage</string>
<string name="AboutText">Keepass2Android is a password manager providing read/write access to KeePass 2.x databases on Android.</string>
<string name="CreditsText">The User Interface is based on a port of KeepassDroid developed by Brian Pellin. Code for database operations is based on KeePass by Dominik Reichl. The Android robot is reproduced or modified from work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License.</string>
<string name="accept">Accept</string>
<string name="add_entry">Add entry</string>
<string name="add_url_entry">Create entry for URL</string>
<string name="add_group">Add group</string>
<string name="add_group_title">Add Group</string>
<string name="edit_group_title">Edit Group</string>
<string name="algorithm">Algorithm</string>
<string name="algorithm_colon">Algorithm</string>
<string name="app_name">Keepass2Android</string>
<string name="short_app_name">KP2A</string>
<string name="app_name_nonet">Keepass2Android Offline</string>
<string name="short_app_name_nonet">KP2A Offline</string>
<string name="app_timeout">Application timeout</string>
<string name="app_timeout_summary">Time before locking database when the application is inactive.</string>
<string name="kill_app_label">Kill application process</string>
<string name="show_kill_app">Close-Button</string>
<string name="show_kill_app_summary">Show a button in password screen to kill the application process (for paranoid users)</string>
<string name="application">Application</string>
<string name="application_settings">Application settings</string>
<string name="security_prefs">Security</string>
<string name="display_prefs">Display</string>
<string name="password_access_prefs">Password entry access</string>
<string name="QuickUnlock_prefs">QuickUnlock</string>
<string name="FileHandling_prefs">File handling</string>
<string name="brackets">Brackets</string>
<string name="cancel">Cancel</string>
<string name="ClearClipboard">Clipboard cleared.</string>
<string name="clipboard_timeout">Clipboard timeout</string>
<string name="clipboard_timeout_summary">Time before clearing clipboard after copying username or password</string>
<string name="copy_username">Select to copy username to clipboard</string>
<string name="copy_password">Select to copy password to clipboard</string>
<string name="available_through_keyboard">Entry is available through KP2A Keyboard</string>
<string name="not_possible_im_picker">Could not open dialog to select input method. Please activate keyboard manually.</string>
<string name="please_activate_keyboard">Please enable the Keepass2Android keyboard in your system settings.</string>
<string name="creating_db_key">Creating database key…</string>
<string name="current_group">Current Group</string>
<string name="current_group_root">Current Group: Root</string>
<string name="database">Database</string>
<string name="digits">Digits</string>
<string name="disclaimer_formal">Keepass2Android comes with ABSOLUTELY NO WARRANTY; This is free software, and you are welcome to redistribute it under the conditions of the GPL version 2 or later.</string>
<string name="ellipsis">\u2026</string>
<string name="enter_filename">Enter database filename</string>
<string name="entry_accessed">Accessed</string>
<string name="entry_cancel">Cancel</string>
<string name="entry_comment">Comments</string>
<string name="entry_tags">Tags</string>
<string name="entry_override_url">Override URL</string>
<string name="entry_confpassword">Confirm password</string>
<string name="entry_created">Created</string>
<string name="entry_expires">Expires</string>
<string name="entry_keyfile">Key file (optional)</string>
<string name="entry_modified">Modified</string>
<string name="entry_password">Password</string>
<string name="entry_save">Save</string>
<string name="entry_title">Name</string>
<string name="entry_url">URL</string>
<string name="entry_user_name">User Name</string>
<string name="entry_extra_strings">Extra string fields</string>
<string name="entry_binaries">File attachments</string>
<string name="error_can_not_handle_uri">Keepass2Android cannot handle this uri.</string>
<string name="error_could_not_create_group">Error creating group.</string>
<string name="error_could_not_create_parent">Could not create parent directory.</string>
<string name="error_database_exists">This file already exists.</string>
<string name="error_database_settings">Failed to determine database settings.</string>
<string name="error_failed_to_launch_link">Failed to launch link.</string>
<string name="error_filename_required">A filename is required.</string>
<string name="error_file_not_create">Could not create file</string>
<string name="error_invalid_db">Invalid database.</string>
<string name="error_invalid_path">Invalid path.</string>
<string name="error_no_name">A name is required.</string>
<string name="error_nopass">A password or a keyfile is required.</string>
<string name="error_pass_gen_type">At least one password generation type must be selected</string>
<string name="error_pass_match">Passwords do not match.</string>
<string name="error_rounds_not_number">Rounds must be a number.</string>
<string name="error_title_required">A title is required.</string>
<string name="error_wrong_length">Enter a positive integer on length field</string>
<string name="FileNotFound">File not found.</string>
<string name="file_browser">File Browser</string>
<string name="generate_password">Generate Password</string>
<string name="group">Group</string>
<string name="hint_comment">comment</string>
<string name="hint_conf_pass">confirm password</string>
<string name="hint_generated_password">generated password</string>
<string name="hint_group_name">Group name</string>
<string name="hint_keyfile">key file</string>
<string name="hint_length">length</string>
<string name="hint_pass">password</string>
<string name="hint_login_pass">Password</string>
<string name="hint_title">name</string>
<string name="hint_url">url</string>
<string name="hint_override_url">override url</string>
<string name="hint_tags">tag1, tag2</string>
<string name="hint_username">username</string>
<string name="InvalidPassword">Invalid password or key file.</string>
<string name="invalid_algorithm">Invalid algorithm.</string>
<string name="invalid_db_sig">Database format not recognized.</string>
<string name="keyfile_does_not_exist">Key file does not exist.</string>
<string name="keyfile_is_empty">Key file is empty.</string>
<string name="length">Length</string>
<string name="list_size_title">Group list size</string>
<string name="list_size_summary">Text size in the group list</string>
<string name="loading_database">Loading database…</string>
<string name="lowercase">Lower-case</string>
<string name="MaskedPassword">*****</string>
<string name="maskpass_title">Mask password</string>
<string name="maskpass_summary">Hide passwords by default</string>
<string name="menu_about">About</string>
<string name="menu_change_key">Change Master Key</string>
<string name="menu_copy_pass">Copy Password</string>
<string name="menu_copy_user">Copy User</string>
<string name="menu_create">Create</string>
<string name="menu_app_settings">Settings</string>
<string name="menu_db_settings">Database settings</string>
<string name="menu_delete">Delete</string>
<string name="menu_move">Move to another group</string>
<string name="menu_donate">Donate a beer...</string>
<string name="menu_edit">Edit</string>
<string name="menu_hide_password">Hide Password</string>
<string name="menu_lock">Lock Database</string>
<string name="menu_open">Open</string>
<string name="menu_rename">Rename</string>
<string name="menu_search">Search</string>
<string name="menu_search_advanced">Advanced Search</string>
<string name="menu_url">Go to URL</string>
<string name="menu_change_db">Change database…</string>
<string name="minus">Minus</string>
<string name="never">Never</string>
<string name="yes">Yes</string>
<string name="no">No</string>
<string name="no_keys">No entries in the database or group.</string>
<string name="no_results">No search results</string>
<string name="no_url_handler">No handler for this url.</string>
<string name="open_recent">Open recent database (click to open)</string>
<string name="omitbackup_title">Don\'t search backup and recycle bin entries</string>
<string name="omitbackup_summary">Omit \'Backup\' and Recycle Bin group from search results</string>
<string name="pass_filename">KeePass database filename</string>
<string name="password_title">Enter database password</string>
<string name="master_key_type">Select master key type:</string>
<string name="progress_create">Creating new database…</string>
<string name="create_database">Create database</string>
<string name="progress_title">Working…</string>
<string name="remember_keyfile_summary">Remembers the location of keyfiles</string>
<string name="remember_keyfile_title">Save keyfile</string>
<string name="remove_from_filelist">Remove</string>
<string name="rijndael">Rijndael (AES)</string>
<string name="root">Root</string>
<string name="rounds">Encryption Rounds</string>
<string name="rounds_explaination">Higher encryption rounds provide additional protection against brute force attacks, but can really slow down loading and saving.</string>
<string name="rounds_hint">rounds</string>
<string name="database_name">Database name</string>
<string name="default_username">Default user name for new entries</string>
<string name="saving_database">Saving database…</string>
<string name="space">Space</string>
<string name="search_label">Search</string>
<string name="show_password">Show password</string>
<string name="sort_name">Sort by name</string>
<string name="sort_db">Sort by creation date</string>
<string name="special">Special</string>
<string name="search_hint">Find what</string>
<string name="search_results">Search results</string>
<string name="search_in">Search in</string>
<string name="select_other_entry">Select another entry</string>
<string name="select_group_then_add">Open the desired group, then press "%1$s"!</string>
<string name="insert_element_here">Insert here</string>
<string name="twofish">Twofish</string>
<string name="underline">Underline</string>
<string name="unsupported_db_version">Unsupported database version.</string>
<string name="uppercase">Upper-case</string>
<string name="warning_read_only">Your sd card is currently read-only. You may not be able to save changes to your database.</string>
<string name="warning_unmounted">Your sd card is not currently mounted on your device. You will not be able to load or create your database.</string>
<string name="version_label">Version</string>
<string name="version_history">Version history</string>
<string name="author">Keepass2Android is developed by Philipp Crocoll.</string>
<string name="further_authors">Thanks to code contributions by %1$s.</string>
<string name="credit_plugin1">The Twofish Cipher Plugin for Keepass was developed by Scott Greenberg and is included in KP2A.</string>
<string name="credit_android_filechooser">android-filechooser was developed by Hai Bison</string>
<string name="please_note">Please note</string>
<string name="contributors">Contributors</string>
<string name="regular_expression">Regular expression</string>
<string name="TanExpiresOnUse_title">Tan expires on use</string>
<string name="TanExpiresOnUse_summary">Mark TAN entries expired when using them</string>
<string name="ShowUsernameInList_title">Display username in list</string>
<string name="ShowUsernameInList_summary">Display usernames below entry titles. Useful for multiple accounts or TANs.</string>
<string name="RememberRecentFiles_title">Remember databases</string>
<string name="RememberRecentFiles_summary">Remember recently opened databases and show them in the Open database screen.</string>
<string name="kp2a_findUrl">Keepass2Android: Find password</string>
<string name="excludeExpiredEntries">Exclude expired entries</string>
<string name="search_options">Options</string>
<string name="caseSensitive">Case sensitive</string>
<string name="start_open_file">Open file...</string>
<string name="start_create">Create new database...</string>
<string name="start_open_url">Open URL...</string>
<string name="start_create_import">Import file to new database...</string>
<string name="enter_filename_details_url">The complete URL must be specified including protocol like http://.</string>
<string name="enter_filename_details_create_import">File to import will be selected in the next step.</string>
<string name="enable_quickunlock">Enable QuickUnlock</string>
<string name="QuickUnlock_label">Enter last %1$d characters of your password:</string>
<string name="QuickUnlock_button">QuickUnlock!</string>
<string name="QuickUnlock_lockButton">Close database</string>
<string name="QuickUnlockDefaultEnabled_title">Enable QuickUnlock by default</string>
<string name="QuickUnlockDefaultEnabled_summary">Defines whether QuickUnlock is enabled by default or not.</string>
<string name="QuickUnlockIconHidden_title">Hide QuickUnlock icon</string>
<string name="QuickUnlockIconHidden_summary">QuickUnlock unfortunately does not work without displaying a notification icon. Select this option to use a transparent icon.</string>
<string name="QuickUnlockLength_title">Length of QuickUnlock key</string>
<string name="QuickUnlockLength_summary">Maximum number of characters used as QuickUnlock password.</string>
<string name="QuickUnlock_fail">QuickUnlock failed: incorrect password!</string>
<string name="BinaryDirectory_title">File attachments directory</string>
<string name="BinaryDirectory_summary">Directory where file attachments are saved to.</string>
<string name="SaveAttachmentDialog_title">Save attachment</string>
<string name="SaveAttachmentDialog_text">Please select where to save the attachment.</string>
<string name="SaveAttachmentDialog_save">Save to SD card</string>
<string name="SaveAttachmentDialog_open">Save to cache and open</string>
<string name="SaveAttachment_doneMessage">Saved file to %1$s.</string>
<string name="SaveAttachment_Failed">Could not save attachment to %1$s.</string>
<string name="error_invalid_expiry_date">Invalid date/time format for expiry date!</string>
<string name="error_string_key">A field name is required for each string.</string>
<string name="field_name">Field Name</string>
<string name="field_value">Field value</string>
<string name="protection">Protected field</string>
<string name="add_binary">Add file attachment...</string>
<string name="add_extra_string">Add additional string</string>
<string name="delete_extra_string">Delete additional string</string>
<string name="database_loaded_quickunlock_enabled">%1$s: Locked. QuickUnlock enabled.</string>
<string name="database_loaded_unlocked">%1$s: Unlocked.</string>
<string name="credentials_dialog_title">Enter server credentials</string>
<string name="UseFileTransactions_title">File transactions</string>
<string name="UseFileTransactions_summary">Use file transactions for writing databases</string>
<string name="LockWhenScreenOff_title">Lock when screen off</string>
<string name="LockWhenScreenOff_summary">Lock the database when screen is switched off.</string>
<string name="UseOfflineCache_title">Database caching</string>
<string name="UseOfflineCache_summary">Keep a copy of remote database files in the application cache directory. This allows to use remote databases even when offline.</string>
<string name="AcceptAllServerCertificates_title">SSL certificates</string>
<string name="AcceptAllServerCertificates_summary">Define the behavior when certificate validation fails. Note: you can install certificates on your device if validation fails!</string>
<string name="ClearOfflineCache_title">Clear cache?</string>
<string name="ClearOfflineCache_question">This will delete all cached database files. Any changes you made while being offline which have not yet been synchronized will be lost! Continue?</string>
<string name="CheckForFileChangesOnSave_title">Check for modifications</string>
<string name="CheckForFileChangesOnSave_summary">Check whether the file was modified externally before saving changes.</string>
<string name="ShowCopyToClipboardNotification_title">Clipboard notifications</string>
<string name="ShowCopyToClipboardNotification_summary">Make username and password accessible through the notification bar and clipboard. Beware of password sniffers!</string>
<string name="ShowKp2aKeyboardNotification_title">KP2A keyboard notification</string>
<string name="ShowKp2aKeyboardNotification_summary">Make full entry accessible through the KP2A keyboard (recommended).</string>
<string name="OpenKp2aKeyboardAutomatically_title">Keyboard selection dialog</string>
<string name="OpenKp2aKeyboardAutomatically_summary">Open keyboard selection dialog when entry is available through KP2A keyboard after search.</string>
<string name="ShowUnlockedNotification_title">Notification while unlocked</string>
<string name="ShowUnlockedNotification_summary">Show an ongoing notification while the database is unlocked.</string>
<string name="PreloadDatabaseEnabled_title">Pre-load database file</string>
<string name="PreloadDatabaseEnabled_summary">Start background loading or downloading of the database file during password entry.</string>
<string name="AskOverwriteBinary">Do you want to overwrite the existing binary with the same name?</string>
<string name="AskOverwriteBinary_title">Overwrite existing binary?</string>
<string name="AskOverwriteBinary_yes">Overwrite</string>
<string name="AskOverwriteBinary_no">Rename</string>
<string name="AttachFailed">Failed to add file attachment.</string>
<string name="RecycleBin">Recycle Bin</string>
<string name="AskDeletePermanentlyEntry">Do you want to delete this entry permanently? Press No to recycle.</string>
<string name="AskDeletePermanentlyGroup">Do you want to delete this group permanently? Press No to recycle.</string>
<string name="AskDeletePermanently_title">Delete permanently?</string>
<string name="AskReloadFile_title">Reload file?</string>
<string name="AskReloadFile">The file which is currently open was changed by another program. Do you want to reload it?</string>
<string name="AskDiscardChanges">Do you really want to discard the changes made? (The Save button is at the top of the form.)</string>
<string name="AskDiscardChanges_title">Discard changes?</string>
<string name="suggest_improvements">Suggest or vote for improvements</string>
<string name="rate_app">Rate this app</string>
<string name="translate_app">Translate KP2A</string>
<string name="AddingEntry">Adding entry…</string>
<string name="AddingGroup">Adding group…</string>
<string name="DeletingEntry">Deleting entry…</string>
<string name="DeletingGroup">Deleting group…</string>
<string name="SettingPassword">Setting password…</string>
<string name="UndoingChanges">Undoing changes…</string>
<string name="TransformingKey">Transforming master key…</string>
<string name="DecodingDatabase">Decoding database…</string>
<string name="ParsingDatabase">Parsing database…</string>
<string name="CheckingTargetFileForChanges">Checking target file for changes…</string>
<string name="TitleSyncQuestion">Merge changes?</string>
<string name="MessageSyncQuestion">The database file was modified externally. Do you want to load and merge the changes before saving? Select No if you want to overwrite the external changes.</string>
<string name="SynchronizingDatabase">Merging changes…</string>
<string name="YesSynchronize">Yes, merge</string>
<string name="NoOverwrite">No, overwrite</string>
<string name="SynchronizingCachedDatabase">Synchronizing cached database…</string>
<string name="DownloadingRemoteFile">Downloading remote file…</string>
<string name="UploadingFile">Uploading file…</string>
<string name="RestoringRemoteFile">Restoring remote file…</string>
<string name="FilesInSync">Files are in sync.</string>
<string name="SynchronizedDatabaseSuccessfully">Database synchronized successfully!</string>
<string name="CheckingDatabaseForChanges">Checking database for changes…</string>
<string name="CouldNotSaveToRemote">Could not save to remote: %1$s. Save again or use the Synchronize menu when remote connection is available again.</string>
<string name="CouldNotLoadFromRemote">Could not open from remote: %1$s. Loaded file from local cache. You can still make changes in the database and synchronize them later.</string>
<string name="UpdatedRemoteFileOnLoad">Updated remote file.</string>
<string name="NotifyOpenFromLocalDueToConflict">Opened local file due to conflict with changes in remote file. Use Synchronize menu to merge.</string>
<string name="LoadedFromRemoteInSync">Remote file and cache are synchronized.</string>
<string name="UpdatedCachedFileOnLoad">Updated local cache copy of %1$s.</string>
<string name="RemoteDatabaseUnchanged">No changes detected.</string>
<string name="ResolvedCacheConflictByUsingRemoteOtpAux">Updated cached OTP auxiliary file: Remote counter was higher.</string>
<string name="ResolvedCacheConflictByUsingLocalOtpAux">Updated remote OTP auxiliary file: Local counter was higher.</string>
<string name="SynchronizingOtpAuxFile">Synchronizing OTP auxiliary file…</string>
<string name="database_file">database file</string>
<string name="otp_aux_file">OTP auxiliary file</string>
<string name="ErrorOcurred">An error occured:</string>
<string name="synchronize_database_menu">Synchronize database…</string>
<string name="CannotMoveGroupHere">Cannot move group to this group.</string>
<string name="donate_question">Today, it\'s Oktoberfest! If you like Keepass2Android: wouldn\'t today be a good day to buy me a beer?</string>
<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</string>
<string name="hint_sftp_port">port</string>
<string name="select_storage_type">Select the storage type:</string>
<string name="filestoragename_file">Local file</string>
<string name="filestoragename_androidget">Get from third-party app</string>
<string name="filestoragename_androidsend">Send to third-party app</string>
<string name="filestoragename_ftp">FTP</string>
<string name="filestoragename_http">HTTP (WebDav)</string>
<string name="filestoragename_https">HTTPS (WebDav)</string>
<string name="filestoragename_dropbox">Dropbox</string>
<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">SkyDrive</string>
<string name="filestoragename_sftp">SFTP (SSH File Transfer)</string>
<string name="filestorage_setup_title">File access initialization</string>
<string name="database_location">Database location</string>
<string name="help_database_location">You can store your database locally on your Android device or in the cloud (non-Offline version only). Keepass2Android makes the database available even if you are offline. As the database is securely encrypted with AES 256 bit encryption, nobody will be able to access your passwords except you. We recommend to select Dropbox: It\'s accessible on all your devices and even provides backups of previous file versions.</string>
<string name="hint_database_location">Select where you want to store the database:</string>
<string name="button_change_location">Change location</string>
<string name="master_password">Master password</string>
<string name="help_master_password">Your database is encrypted with the password you enter here. Choose a strong password in order to keep the database safe! Tip: Make up a sentence or two and use the first letters of the words as password. Include punctuation marks.</string>
<string name="hint_master_password">Select a master password to protect your database:</string>
<string name="key_file">Key file</string>
<string name="help_key_file">A key file is basically a password stored in a file. Key files are typically stronger than master passwords, because the key can be a lot more complicated; however it\'s also harder to keep them secret. If you store your database in the cloud, don\'t store the key file there as well! This would make it completely useless! Important: Do not change the contents of the key file after creating the database!</string>
<string name="hint_key_file">Choose if you want to use a key file in addition to your master password:</string>
<string name="use_key_file">Use key file</string>
<string name="error_adding_keyfile">Error while adding the keyfile!</string>
<string name="init_otp">Load OTP auxiliary file…</string>
<string name="otp_explanation">Enter the next One-time-passwords (OTPs). Swipe your Yubikey NEO at the back of your device to enter via NFC.</string>
<string name="otp_hint">OTP %1$d</string>
<string name="CouldntLoadOtpAuxFile">Could not load auxiliary OTP file!</string>
<string name="CouldntLoadOtpAuxFile_Hint">Please use the OtpKeyProv plugin in KeePass 2.x (PC) to configure your database for use with OTPs!</string>
<string name="otp_discarded_because_no_db">Please select database first. OTP is discarded for security reasons.</string>
<string name="otp_discarded_no_space">OTP discarded: All OTPs already entered!</string>
<string name="otp_discarded_because_db_open">Please close database first. OTP is discarded.</string>
<string name="otps_pending">(One or more OTPs already available)</string>
<string name="otpsecret_hint">OTP secret (e.g. 01 23 ab cd…)</string>
<string name="CouldntParseOtpSecret">Error parsing OTP secret!</string>
<string name="OtpKeyError">Failed to create OTP key! Make sure you have entered the correct OTPs.</string>
<string name="ErrorUpdatingOtpAuxFile">Error updating OTP auxiliary file!</string>
<string name="SavingOtpAuxFile">Saving auxiliary OTP file…</string>
<string name="loading">Loading…</string>
<string name="get_regular_version">Get more storage types</string>
<string name="CertificateWarning">Warning: Server certificate validation failed: %1$s. Install appropriate root certificate on your device or see settings!</string>
<string name="CertificateFailure">Error: Server certificate validation failed! Install appropriate root certificate on your device or see settings!</string>
<string name="ChangeLog_title">Change log</string>
<string name="ChangeLog_0_9_2">
<b>Version 0.9.2</b>\n
* Added OTP support (compatible with OtpKeyProv plugin)\n
* Integrated NFC support for OTPs from YubiKey NEO \n
* Several UI improvements\n
* Integrated Keepass 2.24 library\n
* Added option to kill the app process (see settings)\n
* Improved SSL certificate validation\n
* Bug fixes\n
</string>
<string name="ChangeLog_0_9_1">
<b>Version 0.9.1</b>\n
* Integrated SkyDrive support (Keepass2Android regular edition only)\n
* Fixed problems with Google Drive integration\n
* Added NTLM support
</string>
<string name="ChangeLog_0_9">
<b>Version 0.9</b>\n
* Integrated Dropbox and Google Drive support (read/write databases; Keepass2Android regular edition only)\n
* Integrated custom file browser (based on android-filechooser by HBA)\n
* Improved user interface for creating new databases\n
* Included custom font DejaVu Sans Mono for displaying passwords\n
* Bug fixes
</string>
<string name="ChangeLog_0_8_6">
<b>Version 0.8.6</b>\n
* Support for Twofish cipher\n
* Allow editing of groups\n
* Allow moving of entries and groups\n
* QuickUnlock icon can be made transparent (see settings)\n
* Bug fixes
</string>
<string name="ChangeLog_0_8_5">
<b>Version 0.8.5</b>\n
* Remote files are stored in the local application cache to allow offline usage (including editing and later synchronization). See settings. \n
* Notification icon to visualize the lock-state of the database (see settings)\n
* Improved determination of lock-state in some situations\n
* Database files are loaded to memory while you are typing your password for increased loading speed (see settings)\n
* Entries can be added to root group\n
* Bug fixes (resolving reference fields, problems with keyboard on Italian an Chinese devices)
</string>
<string name="ChangeLog_0_8_4">
<b>Version 0.8.4</b>\n
* External database changes are detected and merged when saving\n
* Improved loading performance\n
* Improved search toolbar with suggestions\n
* New App logo!\n
* Added support for .kdbp format for faster loading/saving\n
* Improved editing of extra strings and hidden display when protected\n
Thanks to Alex Vallat for his code contributions!\n
Thanks to Niki Hüttner (www.close-cut.de) for the new logo!\n
</string>
<string name="ChangeLog_0_8_3"><b>Version 0.8.3</b>\n
* Username/TAN index displayed in entry list (see settings)\n
* Entries can be created if search from browser doesn\'t return results\n
* KP2A keyboard provides possibility to search for credentials for current app\n
* App automatically closes after selecting an entry for use in keyboard\n
* Keyboard selection dialog automatically opens after search for URL (see settings)\n
* Placeholders in entry fields are replaced before copying (most placeholders supported)\n
* minor bug fixes
</string>
<string name="ChangeLog_0_8_2"><b>Version 0.8.2</b>\n
* Support for Digest Authentication in WebDAV\n
* Bugfixes (OI File manager, Open URL)
</string>
<string name="ChangeLog_0_8_1"><b>Version 0.8.1</b>\n
* KP2A Offline and "Online" can be installed both again\n
* Added new translations (thanks to all contributors!)
</string>
<string name="ChangeLog_0_8"><b>Version 0.8</b>\n
* Improved user interface especially for Android 4.x devices\n
* Allow using deliberate file managers for selecting existing files\n
* Added safer way for opening attachments (through cache directory)\n
* fixed bugs in Edit activity\n
* probably introduced new bugs :-)
</string>
<string name="ChangeLog_keptDonate">Extended possibility to donate a beer or something else</string>
<string name="ChangeLog_0_7"><b>Version 0.7</b>\n
* Increased loading speed: key transformations now 10x faster!\n
* Added Keepass2Android soft-keyboard: Switch to this keyboard for entering credentials. Shields you from clipboard-based password sniffers (disable old clipboard notifications in the options)\n
* Added option to donate a beer or something else (see menu)</string>
<string name="ChangeLog"><b>Version 0.6.2</b>\n
* Google Drive/Dropbox/... integration: Use the official Google Drive or Dropbox App and open any .kdbx-file. This will now bring up KP2A.\n
* Improved Search Dialog \n
* Improved search results for Share URL with subdomains\n
* Added options to give feedback, and rate and translate the app in the menu\n
\n
<b>Version 0.6.1</b>\n
* Detect when database changes in the background (i.e. due to activity of a sync app)\n
* Improved searching for URLs from the browser\n
* Confirm dialog when discarding changes\n
\n
<b>Version 0.6</b>\n
Initial public release
</string>
<string-array name="clipboard_timeout_options">
<item>30 seconds</item>
<item>1 minute</item>
<item>5 minutes</item>
<item>10 minutes</item>
<item>15 minutes</item>
<item>30 minutes</item>
<item>1 hour</item>
<item>Never</item>
</string-array>
<string-array name="list_size_options">
<item>Small</item>
<item>Medium</item>
<item>Large</item>
</string-array>
<string-array name="cred_remember_modes">
<item>Do not remember username and password</item>
<item>Remember username only</item>
<item>Remember username and password</item>
</string-array>
<string-array name="password_modes">
<item>Password only</item>
<item>Password + Key file</item>
<item>Password + OTP</item>
<item>Password + OTP secret (recovery mode)</item>
</string-array>
<string-array name="AcceptAllServerCertificates_options">
<item>Ignore certificate validation failures</item>
<item>Warn when validation fails</item>
<item>Do not accept invalid certificates</item>
</string-array>
<string name="initial_directory">Initial directory (optional):</string>
</resources>

View File

@@ -0,0 +1,11 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>

View File

@@ -0,0 +1,23 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View File

@@ -0,0 +1,20 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
org.gradle.jvmargs=-Xmx1024m

160
src/java/JavaFileStorageTest-AS/gradlew vendored Normal file
View File

@@ -0,0 +1,160 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

View File

@@ -0,0 +1,90 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -0,0 +1,6 @@
include ':app'
include ':JavaFileStorage'
project(':JavaFileStorage').projectDir = new File(settingsDir,"../JavaFileStorage/app")
include ':android-filechooser'
project(':android-filechooser').projectDir = new File(settingsDir,"../android-filechooser-AS/app")

View File

@@ -32,12 +32,12 @@
<favorites_list name="KP2ASoftkeyboard_AS" />
</component>
<component name="FileEditorManager">
<leaf>
<file leaf-file-name="AutoFillService.java" pinned="false" current-in-tab="true">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file leaf-file-name="AutoFillService.java" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/autofill/AutoFillService.java">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.4856631">
<caret line="399" column="13" selection-start-line="399" selection-start-column="13" selection-end-line="399" selection-end-column="13" />
<state vertical-scroll-proportion="0.0">
<caret line="406" column="0" selection-start-line="406" selection-start-column="0" selection-end-line="406" selection-end-column="0" />
<folding />
</state>
</provider>
@@ -46,7 +46,7 @@
<file leaf-file-name="build.gradle" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/build.gradle">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="-0.0">
<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>
@@ -56,11 +56,9 @@
<file leaf-file-name="Build.class" pinned="false" current-in-tab="false">
<entry file="jar://$USER_HOME$/AppData/Local/Xamarin/Universal/AndroidSDK/platforms/android-23/android.jar!/android/os/Build.class">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="-0.5802469">
<state vertical-scroll-proportion="0.0">
<caret line="78" column="24" selection-start-line="78" selection-start-column="24" selection-end-line="78" selection-end-column="24" />
<folding>
<element signature="class#VERSION_CODES#0;class#Build#0" expanded="false" />
</folding>
<folding />
</state>
</provider>
</entry>
@@ -68,7 +66,7 @@
<file leaf-file-name="AccessibilityService.class" pinned="false" current-in-tab="false">
<entry file="jar://$USER_HOME$/AppData/Local/Xamarin/Universal/AndroidSDK/platforms/android-23/android.jar!/android/accessibilityservice/AccessibilityService.class">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="-1.5061729">
<state vertical-scroll-proportion="0.0">
<caret line="67" column="33" selection-start-line="67" selection-start-column="33" selection-end-line="67" selection-end-column="33" />
<folding />
</state>
@@ -78,11 +76,9 @@
<file leaf-file-name="accserviceconfig.xml" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/app/src/main/res/xml/accserviceconfig.xml">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="-0.9622642">
<state vertical-scroll-proportion="0.0">
<caret line="3" column="35" selection-start-line="3" selection-start-column="12" selection-end-line="3" selection-end-column="35" />
<folding>
<element signature="e#145#181#0" expanded="true" />
</folding>
<folding />
</state>
</provider>
</entry>
@@ -90,7 +86,7 @@
<file leaf-file-name="strings_autofill.xml" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/app/src/main/res/values/strings_autofill.xml">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="-0.3207547">
<state vertical-scroll-proportion="0.0">
<caret line="1" column="10" selection-start-line="1" selection-start-column="10" selection-end-line="1" selection-end-column="10" />
<folding>
<element signature="e#39#524#0" expanded="false" />
@@ -102,7 +98,7 @@
<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="-6.296296">
<state vertical-scroll-proportion="0.0">
<caret line="10" column="31" selection-start-line="10" selection-start-column="31" selection-end-line="10" selection-end-column="31" />
<folding />
</state>
@@ -112,8 +108,18 @@
<file leaf-file-name="settings.gradle" pinned="false" current-in-tab="false">
<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" />
<state vertical-scroll-proportion="0.0">
<caret line="2" column="0" selection-start-line="2" selection-start-column="0" selection-end-line="2" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="AndroidManifest.xml" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/app/src/main/AndroidManifest.xml">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.60714287">
<caret line="19" column="19" selection-start-line="19" selection-start-column="19" selection-end-line="19" selection-end-column="19" />
<folding />
</state>
</provider>
@@ -1156,7 +1162,7 @@
</option>
<option name="modificationStamps">
<map>
<entry key="$PROJECT_DIR$" value="4454500379108" />
<entry key="$PROJECT_DIR$" value="4456763853918" />
</map>
</option>
<option name="projectBuildClasspath">
@@ -1354,6 +1360,8 @@
<option value="$PROJECT_DIR$/app/src/main/java/keepass2android/autofill/AutoFillService.java" />
<option value="$PROJECT_DIR$/local.properties" />
<option value="$PROJECT_DIR$/gradle.properties" />
<option value="$PROJECT_DIR$/settings.gradle" />
<option value="$PROJECT_DIR$/app/src/main/AndroidManifest.xml" />
</list>
</option>
</component>
@@ -1396,7 +1404,6 @@
</navigator>
<panes>
<pane id="PackagesPane" />
<pane id="Scratches" />
<pane id="AndroidView">
<subPane>
<PATH>
@@ -1417,8 +1424,9 @@
</PATH>
</subPane>
</pane>
<pane id="Scope" />
<pane id="ProjectPane" />
<pane id="Scope" />
<pane id="Scratches" />
</panes>
</component>
<component name="PropertiesComponent">
@@ -1674,14 +1682,13 @@
</component>
<component name="ToolWindowManager">
<frame x="-8" y="-8" width="1382" height="744" extended-state="6" />
<editor active="true" />
<editor active="false" />
<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="2" 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" />
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32879046" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Android Model" 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="4" side_tool="true" content_ui="tabs" />
<window_info id="Capture Analysis" 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="4" side_tool="false" content_ui="tabs" />
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32764506" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Android Monitor" 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="8" side_tool="false" content_ui="tabs" />
<window_info id="Captures" 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="2" side_tool="false" content_ui="tabs" />
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
@@ -1691,17 +1698,18 @@
<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="2" 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.32764506" 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.24962063" sideWeight="0.5" order="1" 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.24886535" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
<window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.24886535" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
<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="Application Servers" 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="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" />
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
<window_info id="Message" 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="0" side_tool="false" content_ui="tabs" />
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32764506" sideWeight="0.5" order="1" side_tool="false" 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.32764506" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Android" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32879046" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Maven Projects" 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="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
@@ -1724,6 +1732,88 @@
<watches-manager />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/autofill/AutoFillService.java">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="406" column="0" selection-start-line="406" selection-start-column="0" selection-end-line="406" 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>
</entry>
<entry file="jar://$USER_HOME$/AppData/Local/Xamarin/Universal/AndroidSDK/platforms/android-23/android.jar!/android/os/Build.class">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="78" column="24" selection-start-line="78" selection-start-column="24" selection-end-line="78" selection-end-column="24" />
<folding />
</state>
</provider>
</entry>
<entry file="jar://$USER_HOME$/AppData/Local/Xamarin/Universal/AndroidSDK/platforms/android-23/android.jar!/android/accessibilityservice/AccessibilityService.class">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="67" column="33" selection-start-line="67" selection-start-column="33" selection-end-line="67" selection-end-column="33" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/app/src/main/res/xml/accserviceconfig.xml">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="3" column="35" selection-start-line="3" selection-start-column="12" selection-end-line="3" selection-end-column="35" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/app/src/main/res/values/strings_autofill.xml">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="1" column="10" selection-start-line="1" selection-start-column="10" selection-end-line="1" selection-end-column="10" />
<folding>
<element signature="e#39#524#0" expanded="false" />
</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="10" column="31" selection-start-line="10" selection-start-column="31" selection-end-line="10" selection-end-column="31" />
<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="2" column="0" selection-start-line="2" selection-start-column="0" selection-end-line="2" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/app/src/main/AndroidManifest.xml">
<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="28" selection-start-line="0" selection-start-column="28" selection-end-line="0" selection-end-column="28" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/app/src/main/res/values-nn/strings_kp2a.xml">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
@@ -1810,7 +1900,7 @@
</entry>
<entry file="file://$PROJECT_DIR$/app/src/main/res/values/strings_autofill.xml">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="-0.3207547">
<state vertical-scroll-proportion="0.0">
<caret line="1" column="10" selection-start-line="1" selection-start-column="10" selection-end-line="1" selection-end-column="10" />
<folding>
<element signature="e#39#524#0" expanded="false" />
@@ -1820,17 +1910,15 @@
</entry>
<entry file="file://$PROJECT_DIR$/app/src/main/res/xml/accserviceconfig.xml">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="-0.9622642">
<state vertical-scroll-proportion="0.0">
<caret line="3" column="35" selection-start-line="3" selection-start-column="12" selection-end-line="3" selection-end-column="35" />
<folding>
<element signature="e#145#181#0" expanded="true" />
</folding>
<folding />
</state>
</provider>
</entry>
<entry file="jar://$USER_HOME$/AppData/Local/Xamarin/Universal/AndroidSDK/platforms/android-23/android.jar!/android/accessibilityservice/AccessibilityService.class">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="-1.5061729">
<state vertical-scroll-proportion="0.0">
<caret line="67" column="33" selection-start-line="67" selection-start-column="33" selection-end-line="67" selection-end-column="33" />
<folding />
</state>
@@ -1838,11 +1926,9 @@
</entry>
<entry file="jar://$USER_HOME$/AppData/Local/Xamarin/Universal/AndroidSDK/platforms/android-23/android.jar!/android/os/Build.class">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="-0.5802469">
<state vertical-scroll-proportion="0.0">
<caret line="78" column="24" selection-start-line="78" selection-start-column="24" selection-end-line="78" selection-end-column="24" />
<folding>
<element signature="class#VERSION_CODES#0;class#Build#0" expanded="false" />
</folding>
<folding />
</state>
</provider>
</entry>
@@ -1855,17 +1941,9 @@
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/local.properties">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="-6.296296">
<caret line="10" column="31" selection-start-line="10" selection-start-column="31" selection-end-line="10" selection-end-column="31" />
<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" />
<caret line="10" column="31" selection-start-line="10" selection-start-column="31" selection-end-line="10" selection-end-column="31" />
<folding />
</state>
</provider>
@@ -1880,8 +1958,24 @@
</entry>
<entry file="file://$PROJECT_DIR$/app/src/main/java/keepass2android/autofill/AutoFillService.java">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.4856631">
<caret line="399" column="13" selection-start-line="399" selection-start-column="13" selection-end-line="399" selection-end-column="13" />
<state vertical-scroll-proportion="0.0">
<caret line="406" column="0" selection-start-line="406" selection-start-column="0" selection-end-line="406" 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="2" column="0" selection-start-line="2" selection-start-column="0" selection-end-line="2" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/app/src/main/AndroidManifest.xml">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.60714287">
<caret line="19" column="19" selection-start-line="19" selection-start-column="19" selection-end-line="19" selection-end-column="19" />
<folding />
</state>
</provider>

View File

@@ -77,17 +77,22 @@
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-safeguard" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/mockable-android-23.jar" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/resources" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content>

View File

@@ -4,8 +4,19 @@
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-sdk android:targetSdkVersion="14" android:minSdkVersion="14"/>
<application android:label="MyKeyboard"
<application
android:killAfterRestore="false">
<!--service android:name="keepass2android.autofill.AutoFillService"
android:enabled="true"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accserviceconfig" />
</service-->
</application>
</manifest>

View File

@@ -1 +1,2 @@
include ':app'

View File

@@ -7,5 +7,5 @@
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Tue Sep 20 20:29:56 CEST 2016
#Mon Sep 05 10:28:53 CEST 2016
sdk.dir=C\:\\Users\\Philipp\\AppData\\Local\\Xamarin\\Universal\\AndroidSDK

View File

@@ -26,8 +26,11 @@ namespace keepass2android
AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(ctx, Android.Resource.Style.ThemeHoloLightDialog));
builder.SetTitle(ctx.GetString(Resource.String.ChangeLog_title));
List<string> changeLog = new List<string>{
#if !NoNet
ctx.GetString(Resource.String.ChangeLog_1_01g),
ctx.GetString(Resource.String.ChangeLog_1_01d),
#endif
ctx.GetString(Resource.String.ChangeLog_1_01),
ctx.GetString(Resource.String.ChangeLog_1_0_0e),
ctx.GetString(Resource.String.ChangeLog_1_0_0),

View File

@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
#if !NoNet
using System.Net.FtpClient;
#endif
using System.Text;
using Android.App;

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="80"
android:versionName="1.0.0-d"
android:versionCode="93"
android:versionName="1.01-g"
package="keepass2android.keepass2android_nonet"
android:installLocation="auto">
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" />

View File

@@ -38,9 +38,10 @@ using TwofishCipher;
using Keepass2android.Pluginsdk;
using keepass2android.Io;
using keepass2android.addons.OtpKeyProv;
#if !NoNet
using Keepass2android.Javafilestorage;
using GoogleDriveFileStorage = keepass2android.Io.GoogleDriveFileStorage;
#endif
namespace keepass2android
{
#if NoNet
@@ -603,12 +604,13 @@ namespace keepass2android
return prefs.GetBoolean(Application.Context.GetString(Resource.String.CheckForDuplicateUuids_key), true);
}
}
#if !NoNet
public ICertificateErrorHandler CertificateErrorHandler
{
get { return new CertificateErrorHandlerImpl(this); }
}
public class CertificateErrorHandlerImpl : Java.Lang.Object, Keepass2android.Javafilestorage.ICertificateErrorHandler
{
private readonly Kp2aApp _app;
@@ -641,7 +643,7 @@ namespace keepass2android
}
}
#endif
private void ShowValidationWarning(string error)
{
ShowToast(Application.Context.GetString(Resource.String.CertificateWarning, error));