Android: как выбрать текст из webview
Я хочу, чтобы пользователь мог выбрать некоторые тексты из webview, и его нужно отправить в виде текстового сообщения. PLS найти способ выбрать текст и скопировать в буфер обмена и извлечь из буфера обмена. я видел много примеров, но ничего мне не помогло... TIA
Изменить
используя код, указанный в ссылке от @orangmoney52. со следующими изменениями
getmethod второй параметр и второй метод вызова метода. если я дам нуль, там придет предупреждение.. какой из них правильный?
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);
}
}
Получение этой ошибки:
05-26 16:41:01.121: WARN/System.err(1096): java.lang.NoSuchMethodException: emulateShiftHeld
Ответы
Ответ 1
Вышеупомянутые ответы выглядят прекрасно, и кажется, что вы пропускаете что-то при выборе текста. Поэтому вам нужно дважды проверить код и найти свой переопределенный любой TouchEvent веб-просмотра.
i Пробовал ниже код, он отлично работает...
Функция
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);
}
}
Вызовите метод выше, где хотите (вы можете поместить кнопку и вызвать этот метод в событии клика): emulateShiftHeld (mWebView);
Ответ 2
Шаг: 1
Создайте собственный класс WebView.
Этот класс переопределит собственную панель действий при длинном нажатии на текст веб-просмотра.
Также он обрабатывает случай выбора для другой версии Android (тестируется на 4.0 и далее)
Этот код принимает выделенный текст с помощью 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);
}
}
Шаг 2:
создать отдельный класс для интерфейса WebView.
Этот класс listnes для события с момента запуска кода javascript
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();
}
}
Шаг 3:
Добавьте menu.xml для пользовательского меню в папку res >
<?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>
Для этого я воспользовался несколькими ссылками, перечисленными ниже:
Спасибо вам, ребята.
как использовать javascript в webview
http://developer.android.com/guide/webapps/webview.html#UsingJavaScript
для ввода javascript
Почему я не могу вставить этот javascript в webview на Android?
для переопределения панели действий по умолчанию
Как переопределить выбор текста по умолчанию для Android-браузера os 4.1+?
для версии 4.0. до 4.3 выбора текста
Невозможно очистить выбор текста в веб-формате
Ответ 3
Самый простой способ, хотя и не такой красивый, как то, что кажется для каждого изготовителя, реализованным функцией копирования/вставки, заключается в следующем:
https://bugzilla.wikimedia.org/show_bug.cgi?id=31484
В принципе, если вы настраиваете свой собственный WebChromeClient
через webview.setWebChromeClient(...)
, то выбор текста по умолчанию отключен. Чтобы включить его, ваш WebChromeClient
должен выполнить следующий метод:
//@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");
}
Ответ 4
@vnshetty, используя код, указанный в ссылке от @orangmoney52, я смог завершить эту проблему несколько месяцев назад. Вы можете создать кнопку в своем меню, которая позволяет копировать текст. Затем в onOptionsItemSelected вы можете иметь такое предложение:
case R.id.select_and_copy: {
Toast.makeText(getApplicationContext(), "Select Text", Toast.LENGTH_SHORT).show();
selectAndCopyText();
return true;
}