mirror of
https://github.com/moparisthebest/keepass2android
synced 2024-11-25 02:32:26 -05:00
implemented experimental AutoFill functionality
This commit is contained in:
parent
bbb32eda26
commit
856d0a5544
@ -3,15 +3,15 @@ package keepass2android.kbbridge;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
public class KeyboardData {
|
public class KeyboardData
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
public static List<StringForTyping> availableFields = new ArrayList<StringForTyping>();
|
public static List<StringForTyping> availableFields = new ArrayList<StringForTyping>();
|
||||||
public static String entryName;
|
public static String entryName;
|
||||||
|
public static String entryId;
|
||||||
|
|
||||||
public static void clear()
|
public static void clear()
|
||||||
{
|
{
|
||||||
availableFields.clear();
|
availableFields.clear();
|
||||||
|
entryName = entryId = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,20 @@
|
|||||||
package keepass2android.kbbridge;
|
package keepass2android.kbbridge;
|
||||||
|
|
||||||
public class StringForTyping {
|
public class StringForTyping {
|
||||||
public String displayName;
|
public String key; //internal identifier (PwEntry string field key)
|
||||||
|
public String displayName; //display name for displaying the key (might be translated)
|
||||||
public String value;
|
public String value;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringForTyping clone(){
|
||||||
|
|
||||||
|
StringForTyping theClone = new StringForTyping();
|
||||||
|
theClone.key = key;
|
||||||
|
theClone.displayName = displayName;
|
||||||
|
theClone.value = value;
|
||||||
|
|
||||||
|
return theClone;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,15 +17,16 @@
|
|||||||
package keepass2android.softkeyboard;
|
package keepass2android.softkeyboard;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.SharedPreferences.Editor;
|
||||||
import android.inputmethodservice.InputMethodService;
|
import android.inputmethodservice.InputMethodService;
|
||||||
import android.inputmethodservice.Keyboard;
|
import android.inputmethodservice.Keyboard;
|
||||||
import android.inputmethodservice.KeyboardView;
|
import android.inputmethodservice.KeyboardView;
|
||||||
import android.provider.Settings;
|
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.Printer;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
@ -37,7 +38,6 @@ import android.view.inputmethod.InputMethodManager;
|
|||||||
import android.view.inputmethod.InputMethodSubtype;
|
import android.view.inputmethod.InputMethodSubtype;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import keepass2android.kbbridge.StringForTyping;
|
import keepass2android.kbbridge.StringForTyping;
|
||||||
@ -231,6 +231,92 @@ public class KP2AKeyboard extends InputMethodService implements
|
|||||||
// Update the label on the enter key, depending on what the application
|
// Update the label on the enter key, depending on what the application
|
||||||
// says it will do.
|
// says it will do.
|
||||||
mCurKeyboard.setImeOptions(getResources(), attribute.imeOptions);
|
mCurKeyboard.setImeOptions(getResources(), attribute.imeOptions);
|
||||||
|
|
||||||
|
tryAutoFillIn(attribute);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean tryAutoFillIn(final EditorInfo attribute) {
|
||||||
|
//auto fill in?
|
||||||
|
//TODO: make this inside an AsyncTask: getText* might be slow
|
||||||
|
CharSequence textAfter = getCurrentInputConnection().getTextAfterCursor(1 /*length*/, 0 /*flags*/);
|
||||||
|
CharSequence textBefore = getCurrentInputConnection().getTextBeforeCursor(1 /*length*/, 0 /*flags*/);
|
||||||
|
boolean hasTextInField = ((textAfter != null) && (textAfter.length() > 0))
|
||||||
|
|| ((textBefore != null) && (textBefore.length()> 0));
|
||||||
|
if (!hasTextInField)
|
||||||
|
{
|
||||||
|
//try to look up saved field ids:
|
||||||
|
if (attribute.fieldId > -1)
|
||||||
|
{
|
||||||
|
SharedPreferences prefs = getApplicationContext().getSharedPreferences("savedFieldIds", MODE_PRIVATE);
|
||||||
|
|
||||||
|
String key = attribute.packageName+"/"+attribute.fieldId;
|
||||||
|
Log.d("KP2AK", "looking up saved field for "+key);
|
||||||
|
|
||||||
|
String fieldKey = prefs.getString(key, "");
|
||||||
|
|
||||||
|
if ("".equals(fieldKey) == false)
|
||||||
|
{
|
||||||
|
Log.d("KP2AK","Found field "+fieldKey);
|
||||||
|
if (commitTextForKey(attribute, fieldKey))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//try to look up saved field hint:
|
||||||
|
if ((attribute.hintText != null) && (attribute.hintText.length() > 0))
|
||||||
|
{
|
||||||
|
SharedPreferences prefs = getApplicationContext().getSharedPreferences("savedFieldHints", MODE_PRIVATE);
|
||||||
|
|
||||||
|
String key = attribute.packageName+"/"+keepass2android.kbbridge.KeyboardData.entryId+"/"+attribute.hintText;
|
||||||
|
Log.d("KP2AK", "looking up saved field hint for "+key);
|
||||||
|
|
||||||
|
String displayName = prefs.getString(key, "");
|
||||||
|
|
||||||
|
if ("".equals(displayName) == false)
|
||||||
|
{
|
||||||
|
Log.d("KP2AK","Found field "+displayName);
|
||||||
|
if (commitTextForKey(attribute, displayName))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//try to look up by hint
|
||||||
|
if ((attribute.hintText != null) && (attribute.hintText.length() > 0))
|
||||||
|
{
|
||||||
|
if (commitTextForKey(attribute, attribute.hintText.toString()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean commitTextForKey(final EditorInfo attribute, String key) {
|
||||||
|
List<StringForTyping> availableFields = keepass2android.kbbridge.KeyboardData.availableFields;
|
||||||
|
for (StringForTyping str: availableFields)
|
||||||
|
{
|
||||||
|
if (str.key.equals(key))
|
||||||
|
{
|
||||||
|
Log.d("KP2AK", "Typing!");
|
||||||
|
commitKp2aString(str.value, attribute);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void commitKp2aString(String value, EditorInfo editorInfo) {
|
||||||
|
getCurrentInputConnection().commitText(
|
||||||
|
value, 0);
|
||||||
|
|
||||||
|
if ((editorInfo.imeOptions&(EditorInfo.IME_MASK_ACTION|EditorInfo.IME_FLAG_NO_ENTER_ACTION)) == EditorInfo.IME_ACTION_NEXT)
|
||||||
|
{
|
||||||
|
Log.d("KP2AK", "action is NEXT");
|
||||||
|
getCurrentInputConnection().performEditorAction(editorInfo.actionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -290,6 +376,7 @@ public class KP2AKeyboard extends InputMethodService implements
|
|||||||
mComposing.setLength(0);
|
mComposing.setLength(0);
|
||||||
updateCandidates();
|
updateCandidates();
|
||||||
InputConnection ic = getCurrentInputConnection();
|
InputConnection ic = getCurrentInputConnection();
|
||||||
|
|
||||||
if (ic != null) {
|
if (ic != null) {
|
||||||
ic.finishComposingText();
|
ic.finishComposingText();
|
||||||
}
|
}
|
||||||
@ -456,51 +543,62 @@ public class KP2AKeyboard extends InputMethodService implements
|
|||||||
String title = "Keepass2Android";
|
String title = "Keepass2Android";
|
||||||
List<StringForTyping> availableFields = keepass2android.kbbridge.KeyboardData.availableFields;
|
List<StringForTyping> availableFields = keepass2android.kbbridge.KeyboardData.availableFields;
|
||||||
|
|
||||||
final ArrayList<String> items = new ArrayList<String>();
|
Log.d("KP2AK", "hint: "+getCurrentInputEditorInfo().hintText);
|
||||||
final ArrayList<String> values = new ArrayList<String>();
|
Log.d("KP2AK", "field name: "+getCurrentInputEditorInfo().fieldName);
|
||||||
|
Log.d("KP2AK", "label: "+getCurrentInputEditorInfo().label);
|
||||||
|
getCurrentInputEditorInfo().dump(new Printer() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void println(String x) {
|
||||||
|
Log.d("KP2AK", x);
|
||||||
|
|
||||||
|
}
|
||||||
|
},"");
|
||||||
|
final ArrayList<StringForTyping> items = new ArrayList<StringForTyping>();
|
||||||
for (StringForTyping entry : availableFields)
|
for (StringForTyping entry : availableFields)
|
||||||
{
|
{
|
||||||
String key = entry.displayName;
|
items.add(entry.clone());
|
||||||
String value = entry.value;
|
|
||||||
items.add(key);
|
|
||||||
values.add(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (keepass2android.kbbridge.KeyboardData.entryName == null)
|
if (keepass2android.kbbridge.KeyboardData.entryName == null)
|
||||||
{
|
{
|
||||||
items.add(getString(R.string.open_entry));
|
StringForTyping openEntry = new StringForTyping();
|
||||||
values.add("KP2ASPECIAL_SelectEntryTask");
|
openEntry.displayName = openEntry.key = getString(R.string.open_entry);
|
||||||
|
openEntry.value = "KP2ASPECIAL_SelectEntryTask";
|
||||||
|
items.add(openEntry);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
title += " ("+keepass2android.kbbridge.KeyboardData.entryName+")";
|
StringForTyping changeEntry = new StringForTyping();
|
||||||
items.add(getString(R.string.change_entry));
|
changeEntry.displayName = changeEntry.key = getString(R.string.change_entry);
|
||||||
values.add("");
|
changeEntry.value = "KP2ASPECIAL_SelectEntryTask";
|
||||||
|
items.add(changeEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mClientPackageName != null) && (mClientPackageName != ""))
|
if ((mClientPackageName != null) && (mClientPackageName != ""))
|
||||||
{
|
{
|
||||||
items.add(getString(R.string.open_entry_for_app,mClientPackageName));
|
StringForTyping searchEntry = new StringForTyping();
|
||||||
values.add("KP2ASPECIAL_SearchUrlTask");
|
searchEntry.key = searchEntry.displayName
|
||||||
|
= getString(R.string.open_entry_for_app,mClientPackageName);
|
||||||
|
searchEntry.value = "KP2ASPECIAL_SearchUrlTask";
|
||||||
|
items.add(searchEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.setTitle(title);
|
builder.setTitle(title);
|
||||||
|
|
||||||
// builder.setMessage("What do you want to type securely?");
|
|
||||||
builder.setItems(items.toArray(new CharSequence[items.size()]),
|
builder.setItems(items.toArray(new CharSequence[items.size()]),
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int item) {
|
public void onClick(DialogInterface dialog, int item) {
|
||||||
|
|
||||||
if (values.get(item).startsWith("KP2ASPECIAL")) {
|
if (items.get(item).value.startsWith("KP2ASPECIAL")) {
|
||||||
//change entry
|
//change entry
|
||||||
Intent startKp2aIntent = getPackageManager().getLaunchIntentForPackage(getApplicationContext().getPackageName());
|
Intent startKp2aIntent = getPackageManager().getLaunchIntentForPackage(getApplicationContext().getPackageName());
|
||||||
//Intent startKp2aIntent = getPackageManager().getLaunchIntentForPackage("keepass2android.keepass2android");
|
|
||||||
if (startKp2aIntent != null)
|
if (startKp2aIntent != null)
|
||||||
{
|
{
|
||||||
startKp2aIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
startKp2aIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||||
startKp2aIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
startKp2aIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
String value = values.get(item);
|
String value = items.get(item).value;
|
||||||
String taskName = value.substring("KP2ASPECIAL_".length());
|
String taskName = value.substring("KP2ASPECIAL_".length());
|
||||||
startKp2aIntent.putExtra("KP2A_APPTASK", taskName);
|
startKp2aIntent.putExtra("KP2A_APPTASK", taskName);
|
||||||
if (taskName.equals("SearchUrlTask"))
|
if (taskName.equals("SearchUrlTask"))
|
||||||
@ -508,14 +606,21 @@ public class KP2AKeyboard extends InputMethodService implements
|
|||||||
startKp2aIntent.putExtra("UrlToSearch", "androidapp://"+mClientPackageName);
|
startKp2aIntent.putExtra("UrlToSearch", "androidapp://"+mClientPackageName);
|
||||||
}
|
}
|
||||||
startActivity(startKp2aIntent);
|
startActivity(startKp2aIntent);
|
||||||
Settings.Secure.getString(
|
|
||||||
getContentResolver(),
|
|
||||||
Settings.Secure.DEFAULT_INPUT_METHOD
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
getCurrentInputConnection().commitText(
|
|
||||||
values.get(item), 0);
|
|
||||||
|
if (getCurrentInputEditorInfo().fieldId > 0)
|
||||||
|
{
|
||||||
|
SharedPreferences savedFieldIds = getApplicationContext().getSharedPreferences("savedFieldIds", MODE_PRIVATE);
|
||||||
|
Editor edit = savedFieldIds.edit();
|
||||||
|
|
||||||
|
edit.putString(getCurrentInputEditorInfo().packageName+"/"+getCurrentInputEditorInfo().fieldId, items.get(item).key);
|
||||||
|
edit.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
commitKp2aString(items.get(item).value, getCurrentInputEditorInfo());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user