I am developing web browser using webview. (Android API level 21)
My goal is when user copy certain text in webView, getting that text value and change it.
I used clipboard change event listner, so when event listener capture copy event, getPrimaryClip, change clip data and setPrimaryClip are processing.
But, event listener is still alive so after setPrimaryClip is called, this process is called again and again...
How can I control just one time?
Or Could you suggest other event listener?
Edit
I referenced this -> made custom contextual action bar.
And with JavaScript code taught by DevTest(answer for this question), I success to make my goal.
The only way to get text selection from a WebView is based on javascript. This is not specific to the action mode, this is how WebView text selection is supposed to be retrieved according to WebView developers' point of view. They deliberately decided to not provide an API to access text selection from Java.
The solution comprise 2 approaches.
With Android API >= 19 you can use evaluateJavascript:
webview.evaluateJavascript("(function(){return window.getSelection().toString()})()",
new ValueCallback<String>()
{
#Override
public void onReceiveValue(String value)
{
Log.v(TAG, "SELECTION:" + value);
}
});
On older builds your only resort is a custom javascript interface with a single method accepting String, which you should call via webview.loadUrl passing the same thing:
webview.loadUrl("javascript:js.callback(window.getSelection().toString())");
where js is the attached javascript interface:
webview.getSettings().setJavaScriptEnabled(true);
webview.addJavascriptInterface(new WebAppInterface(), "js");
and
public class WebAppInterface
{
#JavascriptInterface
public void callback(String value)
{
Log.v(TAG, "SELECTION:" + value);
}
}
Answer from Here
UPDATE:
For modifying and copy data (as your comment), Store the selected value in a member variable like "Seleted_Value" and when on clicking copy button (which is handling action mode - search about custom action mode) modify the "Selected_Value" variable and copy to clipboard using :
ClipboardManager clipboard = (ClipboardManager)
getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("simple text",Selected_Value);
clipboard.setPrimaryClip(clip);
Details here :
Related
My app is designed to be used outdoors (yachting) and displays a web page in a WebView (so I can use all the display area, fix in landscape, disable extraneous inputs like the BACK_KEY etc.).
In the web page, I want to capture the oncontextmenu event on an image like:
<img src="start_line_pin.png" width=55px
id="pinButton"
oncontextmenu = 'startLinePress("PIN"); return false'\>
When I open the page in my app's webview, a long press doesn't fire the event. Android doesn't seem to be passing the longpress event to the web page.
If I open the page directly in Chrome, my startLinePress function is called with a long press as I intended.
So, can anyone suggest how I get the longpress to be passed into the HTML in my WebView instead of it being handled by Android?
One of the most beneficial features of a forum such as this is that it makes you really think about your problem from another point of view.
The answer to my problem lies in the fact that I was trying to use an undocumented feature - the longClick on the web page invoking the oncontextmenu event.
The answer is to use the onLongClick event in java and then pass the event to the javascript function by using the WebView.loadUrl method. My WebView is contentView and the javascript function is javascript:startLinePress as follows:
contentView.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
WebView.HitTestResult hr = ((WebView)v).getHitTestResult();
if(hr.getType() == 5){
contentView.loadUrl("javascript:startLinePress(\"ACTIVITY\")");
}
It needs a little more work to identify which element was clicked, by examining hr.getExtra() but you get the general idea.
Thanks stackoverflow for the great forum.
I would like to create a single-choice dialog form ( similar to what you get when using setSingleChoiceItems on the Dialog builder) that is called from javascript out of a webview and returns its result to javascript.
1) My understanding is that onJsAlert would allow to implement the dialog call but it does only return true or false to the javascript. Is there any workaround that allows this method to return an integer ?
2) The select tag will create such a dialog on small screens, is it possible to invoke that manually from javascript ? I can not use the select tag mainly because I have a lot of items on my page that would call this dialog, having the whole list in a select tag for every single entry would create a huge overhead.
My apologies for not providing any code but I'm stuck in the concept here - I'll post a working solution if I can get some hints on how to do this.
in webview you can use "shouldOverrideUrlLoading" method to fire Dialog.
ex: if you want to fire a alertbox , when you click some link
in html:
<a href='mycall:00'>click here<a>
in java
public boolean shouldOverrideUrlLoading(WebView view, String url){
// if url is eqal to "mycall:00" launch the dialog box
}
to pass a data to javascript
webview.loadUrl("javascript:changeSize(\"" + fontSize + "\")");
here is the JavaScript function which is loaded in webview
function changeSize(fontSize){
$('#article').css('font-size', fontSize);
$('#articleDes').css('font-size', fontSize);
return false;
}
Couldn't you just let have a single js string containing the options you want in your select tags. Then when page is loaded set innerHtml on all select tags that should have the options. That way you don'n need any special integration with the android app. Something along the lines of this using jQuery:
var options = '<option value="foo">Foo</option><option value="bar">Bar</option>'
$(document).ready(function() {
$(select).html(options);
});
Haven't tested it, but something like the above should work.
Otherwise, you could use addJavascriptInterface(Object, String) method to do a tighter integration between your webapp and the android app.
I want to select Text from Webview And Then Highlight only selected apparition of that word. someone has an idea? with javascript does not work because getSelection function return nothing on android webview.
Please help.
As far as I can understand, you can't select text on an Android touch device like you can on a desktop browser (with your mouse).
It seems like the way text is selected on android device only can be copied into the Clipboard or used by the native "Share" app.
Selecting the text => copy it into Clipboard => use the ClipboardManager to fetch it back.
I might is not as simple and smooth as you was hoping for, but maybe it will work out for you :)
Once you have the value of the selected text, your can always pass it to a javascript function that search/replace for it in your html and highlights it, by adding/padding some html to it.
Link to ClipboardManager.
http://developer.android.com/reference/android/text/ClipboardManager.html
Here's a demo of fetching selected text with your mouse on a regular desktop browser:
http://bit.ly/AwggX9
Try running the same with your Android device. The text selection doesn't work the same way. I guess its the Share/Clipboard manager that handles the selection, and not the browser itself.
Good luck, hope you find a solution that works, and will be happy to hear about it.
Have you looked into:
mainpage.showFindDialog("Alice", true);
where mainpage is the WebView...
This will popup above the webview a bar where the text is entered - and then highlight the first occurrence of the text. There are arrows to jump to the next, etc...
Unless you mean you wish to highlight certain words - and have them stay that way - then you need to inject some javascript to do a highlighting function.
The following code will copy your text to clipboard then from clipboard fetch the text and search it..
private void emulateShiftHeld(WebView view)
{
try
{
KeyEvent shiftPressEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_SHIFT_LEFT, 0, 0);
shiftPressEvent.dispatch(view);
}
catch (Exception e)
{
Log.e("dd", "Exception in emulateShiftHeld()", e);
}
}
The following code will highlight you the text you have selected...
ClipboardManager ClipMan = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipMan.setText(ClipMan.getText().toString());
wb.findAll(ClipMan.getText().toString());
try
{
Method m = WebView.class.getMethod("setFindIsUp", Boolean.TYPE);
m.invoke(wb, true);
}
catch (Throwable ignored){}
hey all
i am using a webview in my android app. once i select text on a page i know i can use clipboardmanager to "getText()". But is there a listener that polls whenever a new text is selected?
i want to trigger an event everytime a user selects a text.
thanks a lot :)
For anyone struggling with the same situation, i found the solution in using android 3.0 api 11 , which has an event handler:
ClipboardManager.OnPrimaryClipChangedListener mPrimaryChangeListener
= new ClipboardManager.OnPrimaryClipChangedListener() {
public void onPrimaryClipChanged() {
// Your code in here
}
};
I'm thinking of implementing a HTML welcome panel to our Android app, which presents news and offers on the start-up screen. My question is now, if I present an offer to a specific place (with an id string) can I trigger a callback from the WebView (maybe via Java Script) to the Android app and passing that id string to make it start a new Activity which loads and shows data from a server (JSON) depending on that id string?
The second part is already implemented and working. My main concern is how to get the id string from the HTML WebView back to the Android app when the user clicks on it.
We prefer to use a WebView for that specific welcome panel, because it gives us more flexibility to customize by using HTML.
It's probably better to use WebView.addJavascriptInterface, rather than overload onJsAlert.
yes indeed you can good sir! If you show the data in a javascript Alert, then you can capture it like this. It might not be the most neat way, but it works =)
private void loadWebViewStuff() {
myWebView.setWebChromeClient(new MyWebChromeClient());
myWebView.loadUrl(URL);
}
final class MyWebChromeClient extends WebChromeClient {
#Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
//"message" is what is shown in the alert, here we can do whatever with it
}
}