i want allow user to select some texts from webview and it need to be send as a text message. pls find way to select text and copy to clipboard and extrac开发者_Python百科ting from clipboard. i saw many example but nothing helped me really...TIA
Edit
using the code provided in the link from @orangmoney52. with following changesgetmethod's second parameter and invoke method second parameter. if i give null there warning will come.. which one is correct?
public void selectAndCopyText() {
try {
Method m = WebView.class.getMethod("emulateShiftHeld", Boolean.TYPE);
m.invoke(BookView.mWebView, false);
} catch (Exception e) {
e.printStackTrace();
// fallback
KeyEvent shiftPressEvent = new KeyEvent(0,0,
KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_SHIFT_LEFT,0,0);
shiftPressEvent.dispatch(this);
}
}
Getting this error:
05-26 16:41:01.121: WARN/System.err(1096): java.lang.NoSuchMethodException: emulateShiftHeld
The above answers looks perfectly fine and it seems you're missing something while selecting text. So you need to double check the code and find your overridden any TouchEvent of webview.
i Tried below code it works fine...
Function is
private void emulateShiftHeld(WebView view)
{
try
{
KeyEvent shiftPressEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_SHIFT_LEFT, 0, 0);
shiftPressEvent.dispatch(view);
Toast.makeText(this, "select_text_now", Toast.LENGTH_SHORT).show();
}
catch (Exception e)
{
Log.e("dd", "Exception in emulateShiftHeld()", e);
}
}
Call Above method wherever you want (You can put a button and call this method in its click event): emulateShiftHeld(mWebView);
Step: 1 Create custom WebView class. This class will override the native action bar on long press on the webview text. Also it handles the the selection case for different version of android (tested on 4.0 onwards) This code takes the selected text using javascript.
public class CustomWebView extends WebView {
private Context context;
// override all other constructor to avoid crash
public CustomWebView(Context context) {
super(context);
this.context = context;
WebSettings webviewSettings = getSettings();
webviewSettings.setJavaScriptEnabled(true);
// add JavaScript interface for copy
addJavascriptInterface(new WebAppInterface(context), "JSInterface");
}
// setting custom action bar
private ActionMode mActionMode;
private ActionMode.Callback mSelectActionModeCallback;
private GestureDetector mDetector;
// this will over ride the default action bar on long press
@Override
public ActionMode startActionMode(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 parent.startActionModeForChild(this, mActionModeCallback);
}
private class CustomActionModeCallback implements ActionMode.Callback {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mActionMode = mode;
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(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);
}
}
Step 2: create separate class for WebView interface. This class listnes for event from once javascript code is getting executed
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();
}
}
Step 3: Add menu.xml for custom menu in res > menu folder
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/copy"
android:icon="@drawable/ic_action_copy"
android:showAsAction="always"
android:title="copy">
</item>
<item
android:id="@+id/share"
android:icon="@drawable/ic_action_share"
android:showAsAction="always"
android:title="share">
</item>
I took help of several links listed below to achieve this: Thanks to you guys.
how to use javascript on webview http://developer.android.com/guide/webapps/webview.html#UsingJavaScript
for injecting javascript Why can't I inject this javascript in the webview on android?
for overriding default action bar How to override default text selection of android webview os 4.1+?
for version 4.0. to 4.3 text selection Webview text selection not clearing
The easiest way, although not as pretty as what seems like a per manufacturer implemented copy/paste feature, is the following:
https://bugzilla.wikimedia.org/show_bug.cgi?id=31484
Basically, if you're setting your own WebChromeClient
via webview.setWebChromeClient(...)
then text selection is disabled by default. To enable it your WebChromeClient
needs to have to following method implemented:
//@Override
/**
* Tell the client that the selection has been initiated.
*/
public void onSelectionStart(WebView view) {
// Parent class aborts the selection, which seems like a terrible default.
//Log.i("DroidGap", "onSelectionStart called");
}
@vnshetty, using the code provided in the link from @orangmoney52, I was able to complete this problem a few months ago. You can create a button in your menu that allows you to copy text. Then, in onOptionsItemSelected, you can have a clause like this:
case R.id.select_and_copy: {
Toast.makeText(getApplicationContext(), "Select Text", Toast.LENGTH_SHORT).show();
selectAndCopyText();
return true;
}
精彩评论