Open Custom dialog on text selection of webview
Asked Answered
O

0

10

I have implement code of text selection in webview. It's working very fine without any issue. But I want to open custom dialog instead of default dialog. The which I have use its link is below

How to override default text selection of android webview os 4.1+?

But its not working for custom dialog.

Find code below

public class CustomWebView extends WebView {
private Context context;

private ActionMode mActionMode;
private ActionMode.Callback mSelectActionModeCallback;
private GestureDetector mDetector;

public CustomWebView(Context context) {
    super(context);
    this.context = context;
    WebSettings webviewSettings = getSettings();
    webviewSettings.setJavaScriptEnabled(true);
    // add JavaScript interface for copy
    WebAppInterface webAppInterface = new WebAppInterface(context);
    addJavascriptInterface(webAppInterface, "JSInterface");
}

public CustomWebView(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.context = context;
}

public CustomWebView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    this.context = context;
}

// this will over ride the default action bar on long press
@Override
public ActionMode startActionMode(ActionMode.Callback callback) {
    ViewParent parent = getParent();
    if (parent == null) {
        return null;
    }
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
        String name = callback.getClass().toString();
        if (name.contains("SelectActionModeCallback")) {
            mSelectActionModeCallback = callback;
            mDetector = new GestureDetector(context, new CustomGestureListener());
        }
    }
    CustomActionModeCallback mActionModeCallback = new CustomActionModeCallback();
    return super.startActionMode(mActionModeCallback);
}

private class CustomActionModeCallback implements ActionMode.Callback {

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        MenuInflater inflater = mode.getMenuInflater();
        inflater.inflate(com.depressiv.R.menu.menu, menu);
        return true;
    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false;
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        switch (item.getItemId()) {
            case R.id.copy:
                getSelectedData();
                mode.finish();
                return true;
            case R.id.share:
                mode.finish();
                return true;
            default:
                mode.finish();
                return false;
        }
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            clearFocus();
        } else {
            if (mSelectActionModeCallback != null) {
                mSelectActionModeCallback.onDestroyActionMode(mode);
            }
            mActionMode = null;
        }
    }
}

private void getSelectedData() {

    String js = "(function getSelectedText() {" +
            "var txt;" +
            "if (window.getSelection) {" +
            "txt = window.getSelection().toString();" +
            "} else if (window.document.getSelection) {" +
            "txt = window.document.getSelection().toString();" +
            "} else if (window.document.selection) {" +
            "txt = window.document.selection.createRange().text;" +
            "}" +
            "JSInterface.getText(txt);" +
            "})()";
    // calling the js function
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        evaluateJavascript("javascript:" + js, null);
    } else {
        loadUrl("javascript:" + js);
    }
}

private class CustomGestureListener extends GestureDetector.SimpleOnGestureListener {
    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        if (mActionMode != null) {
            mActionMode.finish();
            return true;
        }
        return false;
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    // Send the event to our gesture detector
    // If it is implemented, there will be a return value
    if (mDetector != null)
        mDetector.onTouchEvent(event);
    // If the detected gesture is unimplemented, send it to the superclass
    return super.onTouchEvent(event);
}
}

WebAppInterface code

public class WebAppInterface {
Context mContext;

WebAppInterface(Context c) {
    mContext = c;
}

@JavascriptInterface
public void getText(String text) {
    // put selected text into clipdata
    ClipboardManager clipboard = (ClipboardManager)
            mContext.getSystemService(Context.CLIPBOARD_SERVICE);
    ClipData clip = ClipData.newPlainText("simple text", text);
    clipboard.setPrimaryClip(clip);
    // gives the toast for selected text
    Toast.makeText(mContext, text, Toast.LENGTH_SHORT).show();
}
}
Oil answered 28/8, 2016 at 17:19 Comment(9)
Would you show us what you have tried, and where exactly you are getting stuck? Presently people will just close this question as a duplicate of the link you have supplied, so it is worth being more specific!Century
@Century : Please see my edited question and help me outOil
No, it won't be me helping - I don't do Android - I mostly just help people ask answerable questions. Thanks for adding the code, have you done any debugging on it? What happens with this code?Century
I have debugging with code but not understandable flow of its execution :(Oil
What happens with this code presently?Century
Its working with selection in webview but it always open default context menuOil
Is WebAppInterface.getText() being called? I presume the answer to this would be useful to an Android developer answering this question. If you don't know, add some file logging here to write a timestamp to a device/emulator text file (and of course check your logger works elsewhere, so it does not just fail silently on a permissions issue).Century
can you add logger and see if code is reaching to correct method on selection ? or debug ? and share resultsBob
I have debug but its not tracing what I actually needOil

© 2022 - 2024 — McMap. All rights reserved.