Final changes for 0.2.0 release.

Fix spacing in PwEntry activity.
This commit is contained in:
Brian Pellin
2009-05-13 21:45:52 -05:00
parent bd1896a604
commit 198b4e81bc
13 changed files with 134 additions and 33 deletions

View File

@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.keepass" package="com.android.keepass"
android:versionName="0.1.8" android:versionCode="9"> android:versionCode="10" android:versionName="0.2.0">
<uses-sdk android:minSdkVersion="1"/>
<application android:label="@string/app_name" android:icon="@drawable/keepass_icon"> <application android:label="@string/app_name" android:icon="@drawable/keepass_icon">
<activity android:name=".KeePass" <activity android:name=".KeePass"
android:label="@string/app_name"> android:label="@string/app_name">

View File

@@ -1,3 +1,8 @@
KeePassDroid (0.2.0)
* Support editing password entries
* Wrap long lines properly in entries
KeePassDroid (0.1.8) KeePassDroid (0.1.8)
* Move database decryption into background thread * Move database decryption into background thread

View File

@@ -44,10 +44,21 @@
android:layout_below="@id/feedback" android:layout_below="@id/feedback"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:autoLink="web"/> android:autoLink="web"/>
<ImageView android:id="@+id/divider2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/Twitter"
android:scaleType="fitXY"
android:src="@android:drawable/divider_horizontal_dark"/>
<TextView android:id="@+id/disclaimer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/divider2"
android:text="@string/disclaimer_formal"/>
<Button android:id="@+id/about_button" <Button android:id="@+id/about_button"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_below="@id/Twitter" android:layout_below="@id/disclaimer"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:text="@string/about_ok" android:text="@string/about_ok"
android:width="100sp"/> android:width="100sp"/>

View File

@@ -35,7 +35,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_below="@id/entry_title_label" android:layout_below="@id/entry_title"
android:text="@string/entry_user_name" /> android:text="@string/entry_user_name" />
<TextView android:id="@+id/entry_user_name" <TextView android:id="@+id/entry_user_name"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -48,7 +48,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_below="@id/entry_user_name_label" android:layout_below="@id/entry_user_name"
android:text="@string/entry_url" /> android:text="@string/entry_url" />
<TextView android:id="@+id/entry_url" <TextView android:id="@+id/entry_url"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -61,7 +61,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_below="@id/entry_url_label" android:layout_below="@id/entry_url"
android:text="@string/entry_password" /> android:text="@string/entry_password" />
<TextView android:id="@+id/entry_password" <TextView android:id="@+id/entry_password"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -75,7 +75,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_below="@id/entry_password_label" android:layout_below="@id/entry_password"
android:text="@string/entry_created" /> android:text="@string/entry_created" />
<TextView android:id="@+id/entry_created" <TextView android:id="@+id/entry_created"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -88,7 +88,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_below="@id/entry_created_label" android:layout_below="@id/entry_created"
android:text="@string/entry_modified" /> android:text="@string/entry_modified" />
<TextView android:id="@+id/entry_modified" <TextView android:id="@+id/entry_modified"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -101,7 +101,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_below="@id/entry_modified_label" android:layout_below="@id/entry_modified"
android:text="@string/entry_accessed" /> android:text="@string/entry_accessed" />
<TextView android:id="@+id/entry_accessed" <TextView android:id="@+id/entry_accessed"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@@ -33,7 +33,7 @@
<string name="current_group_root">Current Group: Root</string> <string name="current_group_root">Current Group: Root</string>
<string name="ClearClipboard">Clipboard cleared.</string> <string name="ClearClipboard">Clipboard cleared.</string>
<string name="menu_about">About</string> <string name="menu_about">About</string>
<string name="AboutText">KeePassDroid is an Android implementation of the KeePass password manager. Currently KeePassDroid can only view databases. It cannot yet create and edit databases. For now, you'll need to create a KeePass database on your PC and transfer it to your SD card.</string> <string name="AboutText">KeePassDroid is an Android implementation of the KeePass password manager. Currently KeePassDroid can only view databases. It cannot yet create databases. For now, you will need to create a KeePass database on your PC and transfer it to your SD card.</string>
<string name="about_feedback">Feedback:</string> <string name="about_feedback">Feedback:</string>
<string name="about_homepage">Homepage:</string> <string name="about_homepage">Homepage:</string>
<string name="about_twitter">Twitter:</string> <string name="about_twitter">Twitter:</string>
@@ -44,4 +44,6 @@
<string name="entry_save">Save</string> <string name="entry_save">Save</string>
<string name="entry_cancel">Cancel</string> <string name="entry_cancel">Cancel</string>
<string name="entry_confpassword">Confirm password:</string> <string name="entry_confpassword">Confirm password:</string>
<string name="disclaimer_formal">KeePassDroid Copyright 2009 Brian Pellin 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>
</resources> </resources>

View File

@@ -42,6 +42,7 @@ import com.android.keepass.keepasslib.PwManagerOutput.PwManagerOutputException;
public class Database { public class Database {
public static HashMap<Integer, WeakReference<PwGroup>> gGroups = new HashMap<Integer, WeakReference<PwGroup>>(); public static HashMap<Integer, WeakReference<PwGroup>> gGroups = new HashMap<Integer, WeakReference<PwGroup>>();
public static HashMap<UUID, WeakReference<PwEntry>> gEntries = new HashMap<UUID, WeakReference<PwEntry>>(); public static HashMap<UUID, WeakReference<PwEntry>> gEntries = new HashMap<UUID, WeakReference<PwEntry>>();
public static HashMap<PwGroup, WeakReference<PwGroup>> gDirty = new HashMap<PwGroup, WeakReference<PwGroup>>();
public static PwGroup gRoot; public static PwGroup gRoot;
public static PwManager mPM; public static PwManager mPM;
public static String mFilename; public static String mFilename;
@@ -62,6 +63,13 @@ public class Database {
} }
public static void UpdateEntry(PwEntry oldE, PwEntry newE) throws IOException, PwManagerOutputException { public static void UpdateEntry(PwEntry oldE, PwEntry newE) throws IOException, PwManagerOutputException {
if ( ! oldE.title.equals(newE.title) ) {
PwGroup parent = oldE.parent;
if ( parent != null ) {
gDirty.put(parent, new WeakReference<PwGroup>(parent));
}
}
oldE.assign(newE); oldE.assign(newE);
SaveData(); SaveData();
@@ -124,6 +132,4 @@ public class Database {
mPM = null; mPM = null;
mFilename = null; mFilename = null;
} }
} }

View File

@@ -42,7 +42,8 @@ import android.widget.TextView;
public class EntryActivity extends LockingActivity { public class EntryActivity extends LockingActivity {
public static final String KEY_ENTRY = "entry"; public static final String KEY_ENTRY = "entry";
public static final String KEY_REFRESH_POS = "refresh_pos";
private static final int MENU_PASS = Menu.FIRST; private static final int MENU_PASS = Menu.FIRST;
private static final int MENU_GOTO_URL = Menu.FIRST + 1; private static final int MENU_GOTO_URL = Menu.FIRST + 1;
private static final int MENU_COPY_USER = Menu.FIRST + 2; private static final int MENU_COPY_USER = Menu.FIRST + 2;
@@ -51,10 +52,11 @@ public class EntryActivity extends LockingActivity {
private static final long CLIP_CLEAR_TIME = 30 * 1000; private static final long CLIP_CLEAR_TIME = 30 * 1000;
public static void Launch(Activity act, PwEntry pw) { public static void Launch(Activity act, PwEntry pw, int pos) {
Intent i = new Intent(act, EntryActivity.class); Intent i = new Intent(act, EntryActivity.class);
i.putExtra(KEY_ENTRY, pw.uuid); i.putExtra(KEY_ENTRY, pw.uuid);
i.putExtra(KEY_REFRESH_POS, pos);
act.startActivityForResult(i,0); act.startActivityForResult(i,0);
} }
@@ -62,6 +64,7 @@ public class EntryActivity extends LockingActivity {
private PwEntry mEntry; private PwEntry mEntry;
private Timer mTimer = new Timer(); private Timer mTimer = new Timer();
private boolean mShowPassword = false; private boolean mShowPassword = false;
private int mPos;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@@ -71,6 +74,7 @@ public class EntryActivity extends LockingActivity {
Intent i = getIntent(); Intent i = getIntent();
UUID uuid = UUID.nameUUIDFromBytes(i.getByteArrayExtra(KEY_ENTRY)); UUID uuid = UUID.nameUUIDFromBytes(i.getByteArrayExtra(KEY_ENTRY));
mPos = i.getIntExtra(KEY_REFRESH_POS, -1);
assert(uuid != null); assert(uuid != null);
mEntry = Database.gEntries.get(uuid).get(); mEntry = Database.gEntries.get(uuid).get();
@@ -114,6 +118,19 @@ public class EntryActivity extends LockingActivity {
tv.setText(text); tv.setText(text);
} }
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ( resultCode == KeePass.EXIT_REFRESH || resultCode == KeePass.EXIT_REFRESH_TITLE ) {
fillData();
if ( resultCode == KeePass.EXIT_REFRESH_TITLE ) {
Intent ret = new Intent();
ret.putExtra(KEY_REFRESH_POS, mPos);
setResult(KeePass.EXIT_REFRESH, ret);
}
}
}
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu); super.onCreateOptionsMenu(menu);

View File

@@ -26,8 +26,10 @@ import java.util.UUID;
import org.phoneid.keepassj2me.PwEntry; import org.phoneid.keepassj2me.PwEntry;
import android.app.Activity; import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.text.method.PasswordTransformationMethod; import android.text.method.PasswordTransformationMethod;
import android.text.method.ScrollingMovementMethod; import android.text.method.ScrollingMovementMethod;
import android.view.Menu; import android.view.Menu;
@@ -44,18 +46,20 @@ public class EntryEditActivity extends LockingActivity {
private PwEntry mEntry; private PwEntry mEntry;
private boolean mShowPassword = false; private boolean mShowPassword = false;
private ProgressDialog mPd;
public static void Launch(Activity act, PwEntry pw) { public static void Launch(Activity act, PwEntry pw) {
Intent i = new Intent(act, EntryEditActivity.class); Intent i = new Intent(act, EntryEditActivity.class);
i.putExtra(KEY_ENTRY, pw.uuid); i.putExtra(KEY_ENTRY, pw.uuid);
act.startActivity(i); act.startActivityForResult(i, 0);
} }
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.entry_edit); setContentView(R.layout.entry_edit);
setResult(KeePass.EXIT_NORMAL);
Intent i = getIntent(); Intent i = getIntent();
UUID uuid = UUID.nameUUIDFromBytes(i.getByteArrayExtra(KEY_ENTRY)); UUID uuid = UUID.nameUUIDFromBytes(i.getByteArrayExtra(KEY_ENTRY));
@@ -107,15 +111,17 @@ public class EntryEditActivity extends LockingActivity {
newEntry.additional = Util.getEditText(act, R.id.entry_comment); newEntry.additional = Util.getEditText(act, R.id.entry_comment);
byte[] password = pass.getBytes(); byte[] password = pass.getBytes();
newEntry.setPassword(password, 0, password.length); newEntry.setPassword(password, 0, password.length);
try { if ( newEntry.title.equals(mEntry.title) ) {
Database.UpdateEntry(mEntry, newEntry); setResult(KeePass.EXIT_REFRESH);
} catch (Exception e) { } else {
Toast.makeText(EntryEditActivity.this, "Failed to store database.", Toast.LENGTH_LONG).show(); setResult(KeePass.EXIT_REFRESH_TITLE);
return;
} }
finish(); mPd = ProgressDialog.show(EntryEditActivity.this, "Working...", "Saving database", true, false);
Thread bkgStore = new Thread(new BackgroundUpdateEntry(mEntry, newEntry));
bkgStore.start();
} }
}); });
@@ -196,5 +202,41 @@ public class EntryEditActivity extends LockingActivity {
TextView tv = (TextView) findViewById(viewId); TextView tv = (TextView) findViewById(viewId);
tv.setText(text); tv.setText(text);
} }
private final Handler uiHandler = new Handler();
public final class AfterSave implements Runnable {
@Override
public void run() {
mPd.dismiss();
finish();
}
}
public final class BackgroundUpdateEntry implements Runnable {
private final PwEntry mOld;
private final PwEntry mNew;
public BackgroundUpdateEntry(PwEntry oldE, PwEntry newE) {
mOld = oldE;
mNew = newE;
}
@Override
public void run() {
try {
Database.UpdateEntry(mOld, mNew);
uiHandler.post(new AfterSave());
} catch (Exception e) {
uiHandler.post(new UIToastTask(EntryEditActivity.this, "Failed to store database."));
setResult(KeePass.EXIT_NORMAL);
return;
}
}
}
} }

View File

@@ -24,13 +24,13 @@ import java.lang.ref.WeakReference;
import org.phoneid.keepassj2me.PwEntry; import org.phoneid.keepassj2me.PwEntry;
import org.phoneid.keepassj2me.PwGroup; import org.phoneid.keepassj2me.PwGroup;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.BaseAdapter;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
@@ -53,6 +53,18 @@ public class GroupActivity extends LockingListActivity {
act.startActivityForResult(i,0); act.startActivityForResult(i,0);
} }
@Override
protected void onResume() {
super.onResume();
if ( Database.gDirty.get(mGroup) != null ) {
Database.gDirty.remove(mGroup);
BaseAdapter adapter = (BaseAdapter) getListAdapter();
adapter.notifyDataSetChanged();
}
}
private int mId; private int mId;
@Override @Override
@@ -65,7 +77,7 @@ public class GroupActivity extends LockingListActivity {
gv.onClick(); gv.onClick();
} else { } else {
PwEntry entry = (PwEntry) mGroup.childEntries.elementAt(position - size); PwEntry entry = (PwEntry) mGroup.childEntries.elementAt(position - size);
PwEntryView pe = new PwEntryView(this, entry); PwEntryView pe = new PwEntryView(this, entry, position);
pe.onClick(); pe.onClick();
} }
} }

View File

@@ -30,7 +30,9 @@ public class KeePass extends Activity {
public static final int EXIT_NORMAL = 0; public static final int EXIT_NORMAL = 0;
public static final int EXIT_LOCK = 1; public static final int EXIT_LOCK = 1;
public static final int EXIT_REFRESH = 2;
public static final int EXIT_REFRESH_TITLE = 3;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);

View File

@@ -19,7 +19,6 @@
*/ */
package com.android.keepass; package com.android.keepass;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
@@ -41,8 +40,6 @@ import android.widget.Toast;
import com.android.keepass.fileselect.FileDbHelper; import com.android.keepass.fileselect.FileDbHelper;
import com.android.keepass.intents.TimeoutIntents; import com.android.keepass.intents.TimeoutIntents;
import com.android.keepass.keepasslib.InvalidKeyFileException; import com.android.keepass.keepasslib.InvalidKeyFileException;
import com.android.keepass.keepasslib.PwManagerOutput;
import com.android.keepass.keepasslib.PwManagerOutput.PwManagerOutputException;
public class PasswordActivity extends Activity { public class PasswordActivity extends Activity {
@@ -62,8 +59,6 @@ public class PasswordActivity extends Activity {
File dbFile = new File(fileName); File dbFile = new File(fileName);
if ( ! dbFile.exists() ) { if ( ! dbFile.exists() ) {
throw new FileNotFoundException(); throw new FileNotFoundException();
//Toast.makeText(act, R.string.FileNotFound, Toast.LENGTH_LONG);
//return;
} }
Intent i = new Intent(act, PasswordActivity.class); Intent i = new Intent(act, PasswordActivity.class);

View File

@@ -30,15 +30,19 @@ public class PwEntryView extends LinearLayout {
private Activity mAct; private Activity mAct;
private PwEntry mPw; private PwEntry mPw;
private TextView mTv;
private int mPos;
public PwEntryView(Activity act, PwEntry pw) { public PwEntryView(Activity act, PwEntry pw, int pos) {
super(act); super(act);
mAct = act; mAct = act;
mPw = pw; mPw = pw;
mPos = pos;
View ev = View.inflate(mAct, R.layout.entry_list_entry, null); View ev = View.inflate(mAct, R.layout.entry_list_entry, null);
TextView tv = (TextView) ev.findViewById(R.id.entry_text); TextView tv = (TextView) ev.findViewById(R.id.entry_text);
tv.setText(mPw.title); tv.setText(mPw.title);
mTv = tv;
LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
@@ -46,8 +50,12 @@ public class PwEntryView extends LinearLayout {
} }
public void refreshTitle() {
mTv.setText(mPw.title);
}
void onClick() { void onClick() {
EntryActivity.Launch(mAct, mPw); EntryActivity.Launch(mAct, mPw, mPos);
} }
} }

View File

@@ -99,7 +99,7 @@ public class PwListAdapter extends BaseAdapter {
private PwEntryView createEntryView(int position, View convertView) { private PwEntryView createEntryView(int position, View convertView) {
PwEntryView ev; PwEntryView ev;
// if (convertView == null || ! (convertView instanceof PwEntryView) ) { // if (convertView == null || ! (convertView instanceof PwEntryView) ) {
ev = new PwEntryView(mAct, filteredEntries.elementAt(position)); ev = new PwEntryView(mAct, filteredEntries.elementAt(position), position);
// } else { // } else {
// ev = (PwEntryView) convertView; // ev = (PwEntryView) convertView;
// ev.setEntry(filteredEntries.elementAt(position)); // ev.setEntry(filteredEntries.elementAt(position));