Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Keyboard Replacement Web-view

Is it possible to embed a web-view into an android keyboard replacement app?

I have an interface written in javascript, and would like to embed that into an android keyboard replacement app. It will need to be able to detect touch events, and send text strings back to the native UI from the web-view.

I have searched google for this, but can not find any onformation on how to create web-view in keyboard replacement app.


EDIT: Created github project for boilerplate based on the on the answer from @ckozl

https://github.com/billymoon/javascript-android-keyboard-boilerplate

like image 501
Billy Moon Avatar asked Feb 07 '12 12:02

Billy Moon


Video Answer


1 Answers

Yes. In short. Not a great idea but technically feasible. Let me walk you through a quick sample project, adapted from the SoftKeyboard sample included with the android SDK. Now there are a number of other technical issues to tackle but this should provide you with a basic starting point....

For starters, lets create a basic layout to use as our keyboard:

\res\layout\input.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>

    <WebView
      android:id="@+id/myWebView"
      android:layout_width="match_parent"
      android:layout_height="600dp"
    />

</FrameLayout>

this is required by android to accept our IME

\res\xml\method.xml:

<?xml version="1.0" encoding="utf-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android"  />

now onto our manifest \AndroidManifest.xml

<manifest 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.android.softkeyboard">

    <uses-sdk android:minSdkVersion="13" android:targetSdkVersion="13" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application android:label="SoftKeyboard">

        <service 
            android:name="SoftKeyboard"
            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>

obviously the uses-sdk and user-permission are up to the app and not required by this code (i'm not using any internet files here, but you could, i tested it and it worked...)

now define a simple keyboard \src...\SoftKeyboard.java:

package com.example.android.softkeyboard;

import android.inputmethodservice.InputMethodService;
import android.inputmethodservice.KeyboardView;
import android.view.View;
import android.webkit.WebView;

public class SoftKeyboard extends InputMethodService implements KeyboardView.OnKeyboardActionListener {

    private WebView myWebView = null;

    @Override 
    public View onCreateInputView() {

        View view = getLayoutInflater().inflate(R.layout.input, null);
        myWebView = (WebView) view.findViewById(R.id.myWebView);
        myWebView.getSettings().setJavaScriptEnabled(true);
        myWebView.addJavascriptInterface(jsInterface, "android");

        return view;
    }

    private Object jsInterface = new Object() {

        @SuppressWarnings("unused")
        public void sendKeys() {
            getCurrentInputConnection().setComposingText("how do ya like me now?", 1);
        }

    };

    @Override
    public void onWindowShown() {

        super.onWindowShown();      
        myWebView.loadUrl("file:///android_asset/keyboard_test.html");
    }

    @Override
    public void onKey(int primaryCode, int[] keyCodes) {}

    @Override
    public void onPress(int primaryCode) {}

    @Override
    public void onRelease(int primaryCode) {}

    @Override
    public void onText(CharSequence text) {}

    @Override
    public void swipeDown() {}

    @Override
    public void swipeLeft() {}

    @Override
    public void swipeRight() {}

    @Override
    public void swipeUp() {}

}

here we basically create a webview then populate it from a asset file and bind a simple interface to it after enabling javascript

here's the asset html: *\assets\keyboard_test.html*

<!DOCTYPE html>
<html>
<head>
<title>test</title>
<style>
button {

    display:block;
    margin:300px auto;
    width:400px;
    padding:60px;

}
</style>
</head>
<body>

<button onclick="android.sendKeys()">yeah buddy!</button>

</body>
</html>

and that's it, run it and you'll get a keyboard with a single button and when you push it the javascript will send text into the input composer...

hope that helps -ck

like image 129
ckozl Avatar answered Oct 19 '22 17:10

ckozl