Add initial sample IME code for autofill keyboard.
* This is just a skeleton IME with a very simple UI, no actual autofill related code is added yet. Test: manual - build using m -j AutofillKeyboard, and install with adb sync Change-Id: I8b22532646fc61af9e9c944f8db11ca1702b008f
This commit is contained in:
10
samples/AutofillKeyboard/Android.bp
Normal file
10
samples/AutofillKeyboard/Android.bp
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
android_app {
|
||||||
|
name: "AutofillKeyboard",
|
||||||
|
srcs: ["**/*.java"],
|
||||||
|
min_sdk_version: "29",
|
||||||
|
target_sdk_version: "30",
|
||||||
|
sdk_version: "current",
|
||||||
|
static_libs: [
|
||||||
|
"androidx.annotation_annotation",
|
||||||
|
],
|
||||||
|
}
|
||||||
17
samples/AutofillKeyboard/AndroidManifest.xml
Executable file
17
samples/AutofillKeyboard/AndroidManifest.xml
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.example.android.autofillkeyboard">
|
||||||
|
<application
|
||||||
|
android:icon="@drawable/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@android:style/Theme.Material.Light">
|
||||||
|
<service
|
||||||
|
android:name="AutofillImeService"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:permission="android.permission.BIND_INPUT_METHOD">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.view.InputMethod" />
|
||||||
|
</intent-filter>
|
||||||
|
<meta-data android:name="android.view.im" android:resource="@xml/method" />
|
||||||
|
</service>
|
||||||
|
</application>
|
||||||
|
</manifest>
|
||||||
BIN
samples/AutofillKeyboard/res/drawable-hdpi/ic_launcher.png
Normal file
BIN
samples/AutofillKeyboard/res/drawable-hdpi/ic_launcher.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
25
samples/AutofillKeyboard/res/layout/input_view.xml
Normal file
25
samples/AutofillKeyboard/res/layout/input_view.xml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
/*
|
||||||
|
**
|
||||||
|
** Copyright 2019, The Android Open Source Project
|
||||||
|
**
|
||||||
|
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
** you may not use this file except in compliance with the License.
|
||||||
|
** You may obtain a copy of the License at
|
||||||
|
**
|
||||||
|
** http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
**
|
||||||
|
** Unless required by applicable law or agreed to in writing, software
|
||||||
|
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
** See the License for the specific language governing permissions and
|
||||||
|
** limitations under the License.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<com.example.android.autofillkeyboard.InputView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/input_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
137
samples/AutofillKeyboard/res/layout/keyboard_10_9_9.xml
Normal file
137
samples/AutofillKeyboard/res/layout/keyboard_10_9_9.xml
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
/*
|
||||||
|
**
|
||||||
|
** Copyright 2019, The Android Open Source Project
|
||||||
|
**
|
||||||
|
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
** you may not use this file except in compliance with the License.
|
||||||
|
** You may obtain a copy of the License at
|
||||||
|
**
|
||||||
|
** http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
**
|
||||||
|
** Unless required by applicable law or agreed to in writing, software
|
||||||
|
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
** See the License for the specific language governing permissions and
|
||||||
|
** limitations under the License.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
style="@style/KeyboardArea">
|
||||||
|
|
||||||
|
<View style="@style/KeyboardRow.Header"/>
|
||||||
|
|
||||||
|
<LinearLayout style="@style/KeyboardRow">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_0_0"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_0_1"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_0_2"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_0_3"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_0_4"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_0_5"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_0_6"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_0_7"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_0_8"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_0_9"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout style="@style/KeyboardRow">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_1_0"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_1_1"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_1_2"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_1_3"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_1_4"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_1_5"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_1_6"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_1_7"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_1_8"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout style="@style/KeyboardRow">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_shift"
|
||||||
|
style="@style/SoftKey.Function"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_2_0"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_2_1"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_2_2"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_2_3"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_2_4"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_2_5"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_2_6"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_del"
|
||||||
|
style="@style/SoftKey.Function"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout style="@style/KeyboardRow">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_symbol"
|
||||||
|
style="@style/SoftKey.Function.Text"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_bottom_0"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_space"
|
||||||
|
style="@style/SoftKey.Space"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_bottom_1"
|
||||||
|
style="@style/SoftKey"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key_pos_enter"
|
||||||
|
style="@style/SoftKey.Function"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
24
samples/AutofillKeyboard/res/values-sw400dp/dimens.xml
Normal file
24
samples/AutofillKeyboard/res/values-sw400dp/dimens.xml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
/*
|
||||||
|
**
|
||||||
|
** Copyright 2019, The Android Open Source Project
|
||||||
|
**
|
||||||
|
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
** you may not use this file except in compliance with the License.
|
||||||
|
** You may obtain a copy of the License at
|
||||||
|
**
|
||||||
|
** http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
**
|
||||||
|
** Unless required by applicable law or agreed to in writing, software
|
||||||
|
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
** See the License for the specific language governing permissions and
|
||||||
|
** limitations under the License.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
<dimen name="keyboard_header_height">42dp</dimen>
|
||||||
|
<dimen name="keyboard_row_height">60dp</dimen>
|
||||||
|
</resources>
|
||||||
27
samples/AutofillKeyboard/res/values/dimens.xml
Normal file
27
samples/AutofillKeyboard/res/values/dimens.xml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
/*
|
||||||
|
**
|
||||||
|
** Copyright 2019, The Android Open Source Project
|
||||||
|
**
|
||||||
|
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
** you may not use this file except in compliance with the License.
|
||||||
|
** You may obtain a copy of the License at
|
||||||
|
**
|
||||||
|
** http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
**
|
||||||
|
** Unless required by applicable law or agreed to in writing, software
|
||||||
|
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
** See the License for the specific language governing permissions and
|
||||||
|
** limitations under the License.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
<dimen name="text_size_normal">24dp</dimen>
|
||||||
|
<dimen name="text_size_symbol">14dp</dimen>
|
||||||
|
|
||||||
|
<dimen name="keyboard_header_height">41dp</dimen>
|
||||||
|
<dimen name="keyboard_row_height">48dp</dimen>
|
||||||
|
</resources>
|
||||||
23
samples/AutofillKeyboard/res/values/strings.xml
Normal file
23
samples/AutofillKeyboard/res/values/strings.xml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
/*
|
||||||
|
**
|
||||||
|
** Copyright 2019, The Android Open Source Project
|
||||||
|
**
|
||||||
|
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
** you may not use this file except in compliance with the License.
|
||||||
|
** You may obtain a copy of the License at
|
||||||
|
**
|
||||||
|
** http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
**
|
||||||
|
** Unless required by applicable law or agreed to in writing, software
|
||||||
|
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
** See the License for the specific language governing permissions and
|
||||||
|
** limitations under the License.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">Autofill-Keyboard</string>
|
||||||
|
</resources>
|
||||||
64
samples/AutofillKeyboard/res/values/styles.xml
Normal file
64
samples/AutofillKeyboard/res/values/styles.xml
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
/*
|
||||||
|
**
|
||||||
|
** Copyright 2019, The Android Open Source Project
|
||||||
|
**
|
||||||
|
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
** you may not use this file except in compliance with the License.
|
||||||
|
** You may obtain a copy of the License at
|
||||||
|
**
|
||||||
|
** http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
**
|
||||||
|
** Unless required by applicable law or agreed to in writing, software
|
||||||
|
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
** See the License for the specific language governing permissions and
|
||||||
|
** limitations under the License.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<style name="KeyboardArea">
|
||||||
|
<item name="android:layout_width">match_parent</item>
|
||||||
|
<item name="android:layout_height">wrap_content</item>
|
||||||
|
<item name="android:layout_gravity">bottom</item>
|
||||||
|
<item name="android:orientation">vertical</item>
|
||||||
|
<item name="android:background">#FFFFFFFF</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="KeyboardRow">
|
||||||
|
<item name="android:layout_width">match_parent</item>
|
||||||
|
<item name="android:layout_height">@dimen/keyboard_row_height</item>
|
||||||
|
<item name="android:orientation">horizontal</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="KeyboardRow.Header">
|
||||||
|
<item name="android:layout_height">@dimen/keyboard_header_height</item>
|
||||||
|
<item name="android:background">#FFEEEEEE</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="SoftKey">
|
||||||
|
<item name="android:layout_width">0dp</item>
|
||||||
|
<item name="android:layout_height">match_parent</item>
|
||||||
|
<item name="android:layout_weight">1</item>
|
||||||
|
<item name="android:gravity">center</item>
|
||||||
|
<item name="android:textColor">#FF000000</item>
|
||||||
|
<item name="android:textSize">@dimen/text_size_normal</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="SoftKey.Function">
|
||||||
|
<item name="android:textColor">#FF333333</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="SoftKey.Function.Text">
|
||||||
|
<item name="android:textColor">#FF333333</item>
|
||||||
|
<item name="android:textSize">@dimen/text_size_symbol</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="SoftKey.Space">
|
||||||
|
<item name="android:layout_weight">5</item>
|
||||||
|
<item name="android:textColor">#FF333333</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
||||||
26
samples/AutofillKeyboard/res/xml/method.xml
Normal file
26
samples/AutofillKeyboard/res/xml/method.xml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
/*
|
||||||
|
**
|
||||||
|
** Copyright 2019, The Android Open Source Project
|
||||||
|
**
|
||||||
|
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
** you may not use this file except in compliance with the License.
|
||||||
|
** You may obtain a copy of the License at
|
||||||
|
**
|
||||||
|
** http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
**
|
||||||
|
** Unless required by applicable law or agreed to in writing, software
|
||||||
|
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
** See the License for the specific language governing permissions and
|
||||||
|
** limitations under the License.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<input-method xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<subtype
|
||||||
|
android:label="AutofillKeyboard"
|
||||||
|
android:imeSubtypeLocale="en_US"
|
||||||
|
android:imeSubtypeMode="keyboard"/>
|
||||||
|
</input-method>
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.example.android.autofillkeyboard;
|
||||||
|
|
||||||
|
import android.inputmethodservice.InputMethodService;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
|
||||||
|
/** The {@link InputMethodService} implementation for Autofill keyboard. */
|
||||||
|
public class AutofillImeService extends InputMethodService {
|
||||||
|
|
||||||
|
private InputView mInputView;
|
||||||
|
private Decoder mDecoder;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateInputView() {
|
||||||
|
mInputView = (InputView) LayoutInflater.from(this).inflate(R.layout.input_view, null);
|
||||||
|
return mInputView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStartInput(EditorInfo attribute, boolean restarting) {
|
||||||
|
super.onStartInput(attribute, restarting);
|
||||||
|
mDecoder = new Decoder(getCurrentInputConnection());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStartInputView(EditorInfo info, boolean restarting) {
|
||||||
|
super.onStartInputView(info, restarting);
|
||||||
|
mInputView.removeAllViews();
|
||||||
|
Keyboard keyboard = Keyboard.qwerty(this);
|
||||||
|
mInputView.addView(keyboard.inflateKeyboardView(LayoutInflater.from(this), mInputView));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComputeInsets(Insets outInsets) {
|
||||||
|
super.onComputeInsets(outInsets);
|
||||||
|
if (mInputView != null) {
|
||||||
|
outInsets.contentTopInsets += mInputView.getTopInsets();
|
||||||
|
}
|
||||||
|
outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_CONTENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle(String data) {
|
||||||
|
mDecoder.decode(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.example.android.autofillkeyboard;
|
||||||
|
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.inputmethod.InputConnection;
|
||||||
|
|
||||||
|
/** Decodes key data and applies changes to {@link InputConnection}. */
|
||||||
|
final class Decoder {
|
||||||
|
|
||||||
|
private final InputConnection mInputConnection;
|
||||||
|
|
||||||
|
Decoder(InputConnection inputConnection) {
|
||||||
|
this.mInputConnection = inputConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
void decode(String data) {
|
||||||
|
if ("DEL".equals(data)) {
|
||||||
|
mInputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
|
||||||
|
} else if ("ENT".equals(data)) {
|
||||||
|
mInputConnection.sendKeyEvent(
|
||||||
|
new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
|
||||||
|
} else if ("SPA".equals(data)) {
|
||||||
|
mInputConnection.sendKeyEvent(
|
||||||
|
new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SPACE));
|
||||||
|
} else {
|
||||||
|
mInputConnection.commitText(data, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.example.android.autofillkeyboard;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
|
/** The root view for the Input Method. */
|
||||||
|
public final class InputView extends FrameLayout {
|
||||||
|
|
||||||
|
// If true, this InputView will simulate Gboard's InputView behavior, which expands its
|
||||||
|
// region to the entire window regardless of its content view's size.
|
||||||
|
private static final boolean EXPAND_TO_WINDOW = false;
|
||||||
|
|
||||||
|
private int mRealHeight;
|
||||||
|
|
||||||
|
public InputView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
mRealHeight = getMeasuredHeight();
|
||||||
|
if (EXPAND_TO_WINDOW && MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
|
||||||
|
setMeasuredDimension(getMeasuredWidth(), MeasureSpec.getSize(heightMeasureSpec));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int getTopInsets() {
|
||||||
|
return getMeasuredHeight() - mRealHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.example.android.autofillkeyboard;
|
||||||
|
|
||||||
|
import android.util.SparseArray;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
/** Controls the visible virtual keyboard view. */
|
||||||
|
final class Keyboard {
|
||||||
|
|
||||||
|
private static final int NUM_STATES = 4;
|
||||||
|
private static final int STATE_SHIFT = 1;
|
||||||
|
private static final int STATE_SYMBOL = 2;
|
||||||
|
|
||||||
|
private final AutofillImeService mAutofillImeService;
|
||||||
|
private final int mViewResId;
|
||||||
|
private final SparseArray<String> mKeyMapping;
|
||||||
|
private View mKeyboardView;
|
||||||
|
private int mState;
|
||||||
|
|
||||||
|
private Keyboard(AutofillImeService autofillImeService, int viewResId,
|
||||||
|
SparseArray<String> keyMapping) {
|
||||||
|
this.mAutofillImeService = autofillImeService;
|
||||||
|
this.mViewResId = viewResId;
|
||||||
|
this.mKeyMapping = keyMapping;
|
||||||
|
this.mState = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getLabel(String data) {
|
||||||
|
if ("SHI".equals(data)) {
|
||||||
|
return "↑";
|
||||||
|
} else if ("DEL".equals(data)) {
|
||||||
|
return "←";
|
||||||
|
} else if ("SYM".equals(data)) {
|
||||||
|
return "?123";
|
||||||
|
} else if ("SPA".equals(data)) {
|
||||||
|
return "[ ]";
|
||||||
|
} else if ("ENT".equals(data)) {
|
||||||
|
return "↩";
|
||||||
|
} else {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Keyboard qwerty(AutofillImeService autofillImeService) {
|
||||||
|
SparseArray<String> keyMapping = new SparseArray<>();
|
||||||
|
keyMapping.put(R.id.key_pos_0_0, "qQ1\u007E");
|
||||||
|
keyMapping.put(R.id.key_pos_0_1, "wW2\u0060");
|
||||||
|
keyMapping.put(R.id.key_pos_0_2, "eE3\u007C");
|
||||||
|
keyMapping.put(R.id.key_pos_0_3, "rR4\u2022");
|
||||||
|
keyMapping.put(R.id.key_pos_0_4, "tT5\u221A");
|
||||||
|
keyMapping.put(R.id.key_pos_0_5, "yY6\u03C0");
|
||||||
|
keyMapping.put(R.id.key_pos_0_6, "uU7\u00F7");
|
||||||
|
keyMapping.put(R.id.key_pos_0_7, "iI8\u00D7");
|
||||||
|
keyMapping.put(R.id.key_pos_0_8, "oO9\u00B6");
|
||||||
|
keyMapping.put(R.id.key_pos_0_9, "pP0\u2206");
|
||||||
|
keyMapping.put(R.id.key_pos_1_0, "aA@\u00A3");
|
||||||
|
keyMapping.put(R.id.key_pos_1_1, "sS#\u00A2");
|
||||||
|
keyMapping.put(R.id.key_pos_1_2, "dD$\u20AC");
|
||||||
|
keyMapping.put(R.id.key_pos_1_3, "fF_\u00A5");
|
||||||
|
keyMapping.put(R.id.key_pos_1_4, "gG&\u005E");
|
||||||
|
keyMapping.put(R.id.key_pos_1_5, "hH-=");
|
||||||
|
keyMapping.put(R.id.key_pos_1_6, "jJ+{");
|
||||||
|
keyMapping.put(R.id.key_pos_1_7, "kK(}");
|
||||||
|
keyMapping.put(R.id.key_pos_1_8, "lL)\\");
|
||||||
|
keyMapping.put(R.id.key_pos_2_0, "zZ*%");
|
||||||
|
keyMapping.put(R.id.key_pos_2_1, "xX\"\u00A9");
|
||||||
|
keyMapping.put(R.id.key_pos_2_2, "cC'\u00AE");
|
||||||
|
keyMapping.put(R.id.key_pos_2_3, "vV:\u2122");
|
||||||
|
keyMapping.put(R.id.key_pos_2_4, "bB;\u2713");
|
||||||
|
keyMapping.put(R.id.key_pos_2_5, "nN![");
|
||||||
|
keyMapping.put(R.id.key_pos_2_6, "mM?]");
|
||||||
|
keyMapping.put(R.id.key_pos_bottom_0, ",,,<");
|
||||||
|
keyMapping.put(R.id.key_pos_bottom_1, "...>");
|
||||||
|
keyMapping.put(R.id.key_pos_shift, "SHI");
|
||||||
|
keyMapping.put(R.id.key_pos_del, "DEL");
|
||||||
|
keyMapping.put(R.id.key_pos_symbol, "SYM");
|
||||||
|
keyMapping.put(R.id.key_pos_space, "SPA");
|
||||||
|
keyMapping.put(R.id.key_pos_enter, "ENT");
|
||||||
|
return new Keyboard(autofillImeService, R.layout.keyboard_10_9_9, keyMapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
View inflateKeyboardView(LayoutInflater inflater, InputView inputView) {
|
||||||
|
mKeyboardView = inflater.inflate(mViewResId, inputView, false);
|
||||||
|
mapKeys();
|
||||||
|
return mKeyboardView;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mapKeys() {
|
||||||
|
for (int i = 0; i < mKeyMapping.size(); i++) {
|
||||||
|
TextView softkey = mKeyboardView.findViewById(mKeyMapping.keyAt(i));
|
||||||
|
String rawData = mKeyMapping.valueAt(i);
|
||||||
|
String data = rawData.length() != NUM_STATES ? rawData : rawData.substring(mState,
|
||||||
|
mState + 1);
|
||||||
|
softkey.setText(getLabel(data));
|
||||||
|
softkey.setOnClickListener(v -> handle(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handle(String data) {
|
||||||
|
if ("SHI".equals(data)) {
|
||||||
|
// Toggle STATE_SHIFT.
|
||||||
|
mState = mState ^ STATE_SHIFT;
|
||||||
|
mapKeys();
|
||||||
|
} else if ("SYM".equals(data)) {
|
||||||
|
// Toggle STATE_SYMBOL and clear STATE_SHIFT.
|
||||||
|
mState = (mState ^ STATE_SYMBOL) & ~STATE_SHIFT;
|
||||||
|
mapKeys();
|
||||||
|
} else {
|
||||||
|
mAutofillImeService.handle(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user