Home » Android » cordova – Can't get backspace to work in codemirror, under Phonegap on Android 4.x?

cordova – Can't get backspace to work in codemirror, under Phonegap on Android 4.x?

Posted by: admin June 15, 2020 Leave a comment

Questions:

I need a web-based text/code editor that behaves well, for my App.

I’m trying to use codemirror under Phonegap and currently I’m having problems getting backspace to work for previously entered text. This is a huge problem for my use case. Now I’ve had a look around and it seems like it’s not a direct codemirror problem, but rather the android and virtual keyboard malarkey, see this question: Android: Backspace in WebView/BaseInputConnection

I’m using Phonegap version 2.6.0, latest codemirror version (as of last night) and testing on Android 4.2.2. This seems to be specific to WebView on Android, could anyone verify that’s not an issue on iOS?

I’m not averse to doing some Java code to rectify the problem, but I’m not sure how to ‘hook’ into the cordova’s implementation of WebView, as all the code that’s exposed to me consists of:

package com.mycompany.MyAppName;

import android.os.Bundle;
import org.apache.cordova.*;

public class MyAppName extends DroidGap{
    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        // Set by <content src="index.html" /> in config.xml
        super.loadUrl(Config.getStartUrl());
        //super.loadUrl("file:///android_asset/www/index.html")
    }
}

unless I’m supposed to look into Cordovas source tree. Essentially what I want to know is how I can implement the solution at the link above in my case. Any help is greatly appreciated!

How to&Answers:

Override init Activity method :

public class ProjectName extends DroidGap
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        init(); // Don't forget this, you'll get runtime error otherwise!

        // The following does the trick:
        super.appView.getSettings().setUseWideViewPort(true);
        super.appView.getSettings().setLoadWithOverviewMode(true);

        // Set by <content src="index.html" /> in config.xml
        super.loadUrl(Config.getStartUrl());
        //super.loadUrl("file:///android_asset/www/index.html")
        super.setIntegerProperty("loadUrlTimeoutValue", 10000); 
    }

    /**
     * Create and initialize web container with default web view objects.
     */
    @Override
    public void init() {
        CordovaWebView webView = new CustomWebView(ProjectName.this);
        CordovaWebViewClient webViewClient;
        if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB)
        {
            webViewClient = new CordovaWebViewClient(this, webView);
        }
        else
        {
            webViewClient = new IceCreamCordovaWebViewClient(this, webView);
        }
        this.init(webView, webViewClient, new CordovaChromeClient(this, webView));
    }

}

Create on CustomWebView which extends CordovaWebView

public class CustomWebView extends CordovaWebView{

    public CustomWebView(Context context) {
        super(context);
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        MyCustomInputConnection connection = new MyCustomInputConnection(this, false);

        return connection;
    }

}

Create your custom InputConnection :

public class MyCustomInputConnection extends BaseInputConnection{

    public MyCustomInputConnection(View targetView, boolean fullEditor) {
        super(targetView, fullEditor);
    }

    @Override
    public boolean deleteSurroundingText(int beforeLength, int afterLength) {       
        // magic: in latest Android, deleteSurroundingText(1, 0) will be called for backspace
        if (beforeLength == 1 && afterLength == 0) {
            // backspace
            return super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
                && super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));
        }

        return super.deleteSurroundingText(beforeLength, afterLength);
    }
}