+ JavaFileStorageTest (test project for FileStorage implementations in Java)

This commit is contained in:
Philipp Crocoll 2014-04-23 20:38:21 +02:00
parent d1cc47057d
commit ed6aae24ca
24 changed files with 1742 additions and 0 deletions

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>JavaFileStorageTest</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,4 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.source=1.6

View File

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.javafilestoragetest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<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" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<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.example.javafilestoragetest.android-filechooser.localfile"
android:exported="false" />
<provider
android:name="group.pals.android.lib.ui.filechooser.providers.history.HistoryProvider"
android:authorities="com.example.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.dropbox.client2.android.AuthActivity"
android:configChanges="orientation|keyboard"
android:launchMode="singleTask" >
<intent-filter>
<!-- db- followed by app key -->
<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>
<intent-filter>
<!-- db- followed by app key -->
<data android:scheme="db-ax0268uydp1ya57" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name="com.example.javafilestoragetest.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.javafilestoragetest.FileStorageSetupActivity"
android:label="@string/title_activity_file_storage_setup" >
</activity>
</application>
</manifest>

View File

@ -0,0 +1,20 @@
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# 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 *;
#}

View File

@ -0,0 +1,17 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-17
android.library.reference.1=../JavaFileStorage
android.library.reference.2=../../../../LiveSDK-for-Android/src
android.library.reference.3=../android-filechooser/code

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

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,48 @@
<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" />
</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,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>

View File

@ -0,0 +1,8 @@
<resources>
<!--
Customize dimensions originally defined in res/values/dimens.xml (such as
screen margins) for sw600dp devices (e.g. 7" tablets) here.
-->
</resources>

View File

@ -0,0 +1,9 @@
<resources>
<!--
Customize dimensions originally defined in res/values/dimens.xml (such as
screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.
-->
<dimen name="activity_horizontal_margin">128dp</dimen>
</resources>

View File

@ -0,0 +1,11 @@
<resources>
<!--
Base application theme for API 11+. This theme completely replaces
AppBaseTheme from res/values/styles.xml on API 11+ devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Holo.Light">
<!-- API 11 theme customizations can go here. -->
</style>
</resources>

View File

@ -0,0 +1,12 @@
<resources>
<!--
Base application theme for API 14+. This theme completely replaces
AppBaseTheme from BOTH res/values/styles.xml and
res/values-v11/styles.xml on API 14+ devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!-- API 14 theme customizations can go here. -->
</style>
</resources>

View File

@ -0,0 +1,7 @@
<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,530 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">JavaFileStorageTest</string>
<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,20 @@
<resources>
<!--
Base application theme, dependent on API level. This theme is replaced
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Light">
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
-->
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>
</resources>

View File

@ -0,0 +1,112 @@
package com.example.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);
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());
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());
}
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,614 @@
package com.example.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 com.dropbox.client2.DropboxAPI;
import keepass2android.javafilestorage.DropboxAppFolderFileStorage;
import keepass2android.javafilestorage.DropboxFileStorage;
import keepass2android.javafilestorage.GoogleDriveFileStorage;
import keepass2android.javafilestorage.JavaFileStorage;
import keepass2android.javafilestorage.JavaFileStorage.FileEntry;
import keepass2android.javafilestorage.SftpStorage;
import keepass2android.javafilestorage.SkyDriveFileStorage;
import keepass2android.kp2afilechooser.StorageFileProvider;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Application;
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 = fs.createFolder(parentPath, testPath);
FileEntry e1 = fs.getFileEntry(parentPath);
FileEntry e2 = fs.getFileEntry(path);
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...");
boolean 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.equals(filename) || 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());
}
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);
}
});
}
static JavaFileStorage createStorageToTest(Context ctx, Context appContext) {
storageToTest = new SftpStorage();
//storageToTest = new SkyDriveFileStorage("000000004010C234", appContext);
//storageToTest = new GoogleDriveFileStorage();
//storageToTest = new DropboxFileStorage(ctx,"4ybka4p4a1027n6", "1z5lv528un9nre8", true);
//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();
//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()).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Ö", 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) {
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();
}
}

View File

@ -0,0 +1,92 @@
package keepass2android.kp2afilechooser;
import java.util.List;
import com.example.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) {
try {
keepass2android.javafilestorage.JavaFileStorage.FileEntry entry = MainActivity.storageToTest.getFileEntry(path);
keepass2android.kp2afilechooser.FileEntry chooserEntry = convertEntry(entry);
return chooserEntry;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
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;
}
}
}