created library project

implemented KP2A button including auto fill
This commit is contained in:
Philipp Crocoll 2014-01-12 02:39:46 +01:00
parent 947678dae2
commit 4ba3d1551c
10 changed files with 670 additions and 473 deletions

View File

@ -12,3 +12,4 @@
# Project target. # Project target.
target=android-17 target=android-17
android.library=true

View File

@ -20,7 +20,7 @@
<keepass2android.softkeyboard.LatinKeyboardView <keepass2android.softkeyboard.LatinKeyboardView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:latin="http://schemas.android.com/apk/res/keepass2android.softkeyboard" xmlns:latin="http://schemas.android.com/apk/res-auto"
android:id="@+id/LatinkeyboardBaseView" android:id="@+id/LatinkeyboardBaseView"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -20,7 +20,7 @@
<keepass2android.softkeyboard.LatinKeyboardView <keepass2android.softkeyboard.LatinKeyboardView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:latin="http://schemas.android.com/apk/res/keepass2android.softkeyboard" xmlns:latin="http://schemas.android.com/apk/res-auto"
android:id="@+id/LatinkeyboardBaseView" android:id="@+id/LatinkeyboardBaseView"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"

View File

@ -20,7 +20,9 @@
<keepass2android.softkeyboard.LatinKeyboardView <keepass2android.softkeyboard.LatinKeyboardView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:latin="http://schemas.android.com/apk/res/keepass2android.softkeyboard"
xmlns:latin="http://schemas.android.com/apk/res-auto"
android:id="@+id/LatinkeyboardBaseView" android:id="@+id/LatinkeyboardBaseView"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -20,7 +20,7 @@
<keepass2android.softkeyboard.LatinKeyboardView <keepass2android.softkeyboard.LatinKeyboardView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:latin="http://schemas.android.com/apk/res/keepass2android.softkeyboard" xmlns:latin="http://schemas.android.com/apk/res-auto"
android:id="@+id/LatinkeyboardBaseView" android:id="@+id/LatinkeyboardBaseView"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -20,7 +20,7 @@
<keepass2android.softkeyboard.LatinKeyboardView <keepass2android.softkeyboard.LatinKeyboardView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:latin="http://schemas.android.com/apk/res/keepass2android.softkeyboard" xmlns:latin="http://schemas.android.com/apk/res-auto"
android:id="@+id/LatinkeyboardBaseView" android:id="@+id/LatinkeyboardBaseView"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -26,7 +26,7 @@
android:background="@drawable/keyboard_popup_panel_background" android:background="@drawable/keyboard_popup_panel_background"
> >
<keepass2android.softkeyboard.LatinKeyboardBaseView <keepass2android.softkeyboard.LatinKeyboardBaseView
xmlns:latin="http://schemas.android.com/apk/res/keepass2android.softkeyboard" xmlns:latin="http://schemas.android.com/apk/res-auto"
android:id="@+id/LatinKeyboardBaseView" android:id="@+id/LatinKeyboardBaseView"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -27,7 +27,7 @@
android:paddingRight="16dip" android:paddingRight="16dip"
> >
<keepass2android.softkeyboard.LatinKeyboardBaseView <keepass2android.softkeyboard.LatinKeyboardBaseView
xmlns:latin="http://schemas.android.com/apk/res/keepass2android.softkeyboard" xmlns:latin="http://schemas.android.com/apk/res-auto"
android:id="@+id/LatinKeyboardBaseView" android:id="@+id/LatinKeyboardBaseView"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -23,6 +23,7 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.XmlResourceParser; import android.content.res.XmlResourceParser;
@ -59,6 +60,7 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.Toast; import android.widget.Toast;
import keepass2android.kbbridge.StringForTyping;
import keepass2android.softkeyboard.LatinIMEUtil.RingCharBuffer; import keepass2android.softkeyboard.LatinIMEUtil.RingCharBuffer;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
@ -156,7 +158,6 @@ public class KP2AKeyboard extends InputMethodService
private boolean mAutoCorrectOn; private boolean mAutoCorrectOn;
// TODO move this state variable outside LatinIME // TODO move this state variable outside LatinIME
private boolean mCapsLock; private boolean mCapsLock;
private boolean mPasswordText;
private boolean mVibrateOn; private boolean mVibrateOn;
private boolean mSoundOn; private boolean mSoundOn;
private boolean mPopupOn; private boolean mPopupOn;
@ -480,16 +481,7 @@ public class KP2AKeyboard extends InputMethodService
TextEntryState.newSession(this); TextEntryState.newSession(this);
// Most such things we decide below in the switch statement, but we need to know
// now whether this is a password text field, because we need to know now (before
// the switch statement) whether we want to enable the voice button.
mPasswordText = false;
int variation = attribute.inputType & EditorInfo.TYPE_MASK_VARIATION; int variation = attribute.inputType & EditorInfo.TYPE_MASK_VARIATION;
if (variation == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD ||
variation == EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) {
mPasswordText = true;
}
mInputTypeNoAutoCorrect = false; mInputTypeNoAutoCorrect = false;
mPredictionOn = false; mPredictionOn = false;
mCompletionOn = false; mCompletionOn = false;
@ -589,9 +581,102 @@ public class KP2AKeyboard extends InputMethodService
// If we just entered a text field, maybe it has some old text that requires correction // If we just entered a text field, maybe it has some old text that requires correction
checkReCorrectionOnStart(); checkReCorrectionOnStart();
tryKp2aAutoFill(attribute);
if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
} }
private boolean tryKp2aAutoFill(final EditorInfo editorInfo) {
//auto fill in?
InputConnection ic = getCurrentInputConnection();
if (ic == null) return false;
ExtractedTextRequest etr = new ExtractedTextRequest();
etr.token = 0; // anything is fine here
ExtractedText et = ic.getExtractedText(etr, 0);
if (et == null)
{
Log.d("KP2AK", "et == null");
}
else
{
Log.d("KP2AK", "et != null "+et.text);
}
boolean hasTextInField = (et != null) && (!TextUtils.isEmpty(et.text));
if (!hasTextInField) //only auto-fill if target field is empty
{
//try to look up saved field ids:
if (editorInfo.fieldId > -1)
{
SharedPreferences prefs = getApplicationContext().getSharedPreferences("savedFieldIds", MODE_PRIVATE);
String key = editorInfo.packageName+"/"+editorInfo.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(editorInfo, fieldKey))
return true;
}
}
//try to look up saved field hint:
if ((editorInfo.hintText != null) && (editorInfo.hintText.length() > 0))
{
SharedPreferences prefs = getApplicationContext().getSharedPreferences("savedFieldHints", MODE_PRIVATE);
String key = editorInfo.packageName+"/"+keepass2android.kbbridge.KeyboardData.entryId+"/"+editorInfo.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(editorInfo, displayName))
return true;
}
}
//try to look up by hint
if ((editorInfo.hintText != null) && (editorInfo.hintText.length() > 0))
{
if (commitTextForKey(editorInfo, editorInfo.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);
onText(value);
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);
}
}
private void checkReCorrectionOnStart() { private void checkReCorrectionOnStart() {
if (mReCorrectionEnabled && isPredictionOn()) { if (mReCorrectionEnabled && isPredictionOn()) {
// First get the cursor position. This is required by setOldSuggestions(), so that // First get the cursor position. This is required by setOldSuggestions(), so that
@ -864,17 +949,6 @@ public class KP2AKeyboard extends InputMethodService
return super.onKeyUp(keyCode, event); return super.onKeyUp(keyCode, event);
} }
private void revertVoiceInput() {
InputConnection ic = getCurrentInputConnection();
if (ic != null) ic.commitText("", 1);
updateSuggestions();
}
private void commitVoiceInput() {
InputConnection ic = getCurrentInputConnection();
if (ic != null) ic.finishComposingText();
updateSuggestions();
}
private void reloadKeyboards() { private void reloadKeyboards() {
mKeyboardSwitcher.setLanguageSwitcher(mLanguageSwitcher); mKeyboardSwitcher.setLanguageSwitcher(mLanguageSwitcher);
@ -1107,7 +1181,125 @@ public class KP2AKeyboard extends InputMethodService
} }
private void onKp2aKeyPressed() { private void onKp2aKeyPressed() {
Toast.makeText(getApplicationContext(), "KP2A", Toast.LENGTH_LONG).show(); AlertDialog.Builder builder = new AlertDialog.Builder(this);
String title = "Keepass2Android";
List<StringForTyping> availableFields = keepass2android.kbbridge.KeyboardData.availableFields;
final EditorInfo attribute = getCurrentInputEditorInfo();
Log.d("KP2AK", "hint: "+attribute.hintText);
Log.d("KP2AK", "field name: "+attribute.fieldName);
Log.d("KP2AK", "label: "+attribute.label);
attribute.dump(new Printer() {
@Override
public void println(String x) {
Log.d("KP2AK", x);
}
},"");
final ArrayList<StringForTyping> items = new ArrayList<StringForTyping>();
for (StringForTyping entry : availableFields)
{
Log.d("KP2AK", entry.displayName);
items.add(entry.clone());
}
if (keepass2android.kbbridge.KeyboardData.entryName == null)
{
StringForTyping openEntry = new StringForTyping();
openEntry.displayName = openEntry.key = getString(R.string.open_entry);
openEntry.value = "KP2ASPECIAL_SelectEntryTask";
items.add(openEntry);
}
else
{
StringForTyping changeEntry = new StringForTyping();
changeEntry.displayName = changeEntry.key = getString(R.string.change_entry);
changeEntry.value = "KP2ASPECIAL_SelectEntryTask";
items.add(changeEntry);
}
final String clientPackageName = attribute.packageName;
if ((clientPackageName != null) && (clientPackageName != ""))
{
StringForTyping searchEntry = new StringForTyping();
searchEntry.key = searchEntry.displayName
= getString(R.string.open_entry_for_app, clientPackageName);
searchEntry.value = "KP2ASPECIAL_SearchUrlTask";
items.add(searchEntry);
}
builder.setTitle(title);
CharSequence[] itemNames = new CharSequence[items.size()];
int i=0;
for (StringForTyping sft: items)
itemNames[i++] = sft.displayName;
builder.setItems(itemNames,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
Log.d("KP2AK", "clicked item: " + items.get(item).key);
if (items.get(item).value.startsWith("KP2ASPECIAL")) {
//change entry
Log.d("KP2AK", "clicked item: " + items.get(item).value);
String packageName = getApplicationContext().getPackageName();
Intent startKp2aIntent = getPackageManager().getLaunchIntentForPackage(packageName);
if (startKp2aIntent != null)
{
startKp2aIntent.addCategory(Intent.CATEGORY_LAUNCHER);
startKp2aIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
String value = items.get(item).value;
String taskName = value.substring("KP2ASPECIAL_".length());
startKp2aIntent.putExtra("KP2A_APPTASK", taskName);
if (taskName.equals("SearchUrlTask"))
{
startKp2aIntent.putExtra("UrlToSearch", "androidapp://"+clientPackageName);
}
startActivity(startKp2aIntent);
} else Log.w("KP2AK", "didn't find intent for "+packageName);
} else {
if (attribute.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();
}
Log.d("KP2AK", "committing text for " + items.get(item).key);
commitKp2aString(items.get(item).value, getCurrentInputEditorInfo());
}
}
});
builder.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
// Create the AlertDialog
AlertDialog dialog = builder.create();
Window window = dialog.getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
lp.token = inputView.getWindowToken();
lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
window.setAttributes(lp);
window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
dialog.show();
} }
@ -1141,7 +1333,6 @@ public class KP2AKeyboard extends InputMethodService
ic.beginBatchEdit(); ic.beginBatchEdit();
if (mPredicting) { if (mPredicting) {
final int length = mComposing.length(); final int length = mComposing.length();
if (length > 0) { if (length > 0) {