How to create Async Task in JavaScript - javascript

In my android application, i have called one javascript method from html page to java page.
this.start = function ()
{
try
{
Mynamespace.myapi.getvalue("myvalue", {
onSuccess: function (data)
{
value= JSON.parse(data);
alert("called");
},
onFailure: function (error) { }
});
}
catch (err) { }
if (value== null) { value= new Object();
};
In the above, getvalue method is called in my java class and returned some values, but before getting the value inside the OnSuccess/OnFailure, the below line is called. How to wait the method up to the callback is called?
if (value== null) { value= new Object();

private class LongOperation extends AsyncTask<String, Void, String>
{
protected void onPreExecute()
{
progressDialog = new ProgressDialog(activity.this);
progressDialog.setTitle("Processing...");
progressDialog.setMessage("Please wait...");
progressDialog.setCancelable(true);
progressDialog.show();
}
protected String doInBackground(String... params)
{
try
{
//Getting data from server
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String result)
{
progressDialog.dismiss();
}
}
How to call this
ProgressDialog progressDialog;
LongOperation mytask = null;
mytask = new LongOperation();
mytask.execute();

I have analyzed more about my query. Finally i got a solution. String that i have loaded with webview was having more single quotes so unable to load with webview. So instead of calling Success failure callback, the next line is called.
Now I have replaced the single quotes "\'" by "\'" in my java class. Working fine. :-)

Related

why is the WebView.evaluateJavascript method called twice?

public static String dataFromJs;
public void androidMethod() {
// initialize static String dataFromJs.
dataFromJs = "";
webView.evaluateJavascript("javascript:jsFuction();", new ValueCallback<String>() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onReceiveValue(String s) {
JsonReader reader = new JsonReader(new StringReader(s));
reader.setLenient(true);
try {
if (reader.peek() != JsonToken.NULL) {
if (reader.peek() == JsonToken.STRING) {
// get string value from javascript and I want to use the value
dataFromJs = reader.nextString();
}
}
} catch (IOException e) {
Log.e("TAG", "MainActivity: IOException", e);
} finally {
try {
reader.close();
} catch (IOException e) {
// NOOP
}
}
}
});
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if(url.endsWith("menu/page.do")) {
androidMethod();
// do something with dataFromJs..
}
}
The androidMethod is my method in android.
I try to use the str what I receieved from javascript.
but webView.evaluateJavascript method always return null at the first time,
the webView.evaluateJavascript is called again and return string value correctly.
Since the return value is null at the first time, so I can't use the androidMethod in another method.
Anyone has good solution??
is it have something to do with this log (The application may be doing too much work on its main thread.) ?
Thank you!

The InvokeScript() Method returns null

The InvokeScript() Method returns null.
JavaScript:
function gpsToAddress(gpsX, gpsY) {
var coords = new daum.maps.LatLng(gpsX, gpsY);
geocoder.coord2detailaddr(coords, CallbackA)}
function CallbackA(status, result) {
if(status===daum.maps.services.Status.OK)
{
return result[0].jibunaddress;
}
}
and C#:
private void f_ret_gpstoaddress(double v_gps_x, double v_gps_y,out string v_address)
{
object[] args = { "gpsToAddress(" + v_gps_x + "," + v_gps_y + ");" };
v_address = (string)webBrowser1.Document.InvokeScript("eval", args);
return;
}
private void button3_Click(object sender, EventArgs e)
{
f_ret_gpstoaddress(37.353933, 127.944739, out v_address);
MessageBox.Show(v_address);
}
the 'args' and 'v_address' returns null and the messageBox returns null, too.
I want to return some values.
Please, help me!
EDIT : OK, I edited the C# code like this:
private string f_ret_gpstoaddress(double v_gps_x, double v_gps_y, out string v_address)
{
var args = "gpsToAddress(" + v_gps_x + "," + v_gps_y + ");" ;
v_address = webBrowser1.Document.InvokeScript("eval",new object[] { args }).ToString();
return v_address;
}
private void button3_Click(object sender, EventArgs e)
{
f_ret_gpstoaddress(37.353933, 127.944739, out v_address);
MessageBox.Show(v_address);
}
So, args is not null, but v_address is still null. What's problem??
Your function gpsToAddress doesn't return anything. But it called a callback function when process is finished.
I suggest to you to pass the callback function when you called the function.
Please look this thread for more details : Make async event synchronous in JavaScript
Edit: Based on the above question :
Create a callback class
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public class Callback
{
// allows an instance of Callback to look like a function to the script
// (allows callback() rather than forcing the script to do callback.callMe)
[System.Runtime.InteropServices.DispId(0)]
public void callMe(string v_address)
{
MessageBox.Show(v_address);
}
}
Call js function with a callback :
private string f_ret_gpstoaddress(double v_gps_x, double v_gps_y, out string v_address)
{
Callback cb = new Callback();
var args = "gpsToAddress(" + v_gps_x + "," + v_gps_y + "," + cb);" ;
v_address = webBrowser1.Document.InvokeScript("eval",new object[] { args }).ToString();
return v_address;
}
The js function take a callback as argument :
function gpsToAddress(gpsX, gpsY, callback) {
function CallbackA(status, result) {
if(status===daum.maps.services.Status.OK)
{
callback(result[0].jibunaddress);
}
else {
callback('');
}
}
var coords = new daum.maps.LatLng(gpsX, gpsY);
geocoder.coord2detailaddr(coords, CallbackA)
}
Edit 2 : (dummy sample)
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
string javascript = #"<html><head><script type='text/javascript'>function gpsToAddress(param1, callback) {
function CallbackA()
{
callback(param1);
}
setTimeout(function() { CallbackA() }, 1000);
}</script></head></html>";
public Form1()
{
InitializeComponent();
webBrowser1.DocumentText = javascript;
}
private void button1_Click(object sender, EventArgs e)
{
Callback cb = new Callback();
webBrowser1.Document.InvokeScript("gpsToAddress", new object[] { 123, cb });
}
}
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public class Callback
{
// allows an instance of Callback to look like a function to the script
// (allows callback() rather than forcing the script to do callback.callMe)
[System.Runtime.InteropServices.DispId(0)]
public void callMe(string v_address)
{
MessageBox.Show(v_address);
}
}
}

Handling native event in javascript android

I have written a native class to download from the internet, and I want to call that code from JavaScript. I can call the native code from JavaScript in webview, but I don't know how to call the native event in JavaScript.
This is the native code :
public class DonwloadTask extends AsyncTask<URL,Void,Long> {
private OnTaskCompleted listener;
private String result;
public DonwloadTask(OnTaskCompleted listener){
this.listener=listener;
}
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
StringBuilder resultBuilder = new StringBuilder();
for (int i = 0; i < count; i++) {
try {
// Read all the text returned by the server
InputStreamReader reader = new InputStreamReader(urls[i].openStream());
BufferedReader in = new BufferedReader(reader);
String resultPiece;
while ((resultPiece = in.readLine()) != null) {
resultBuilder.append(resultPiece);
}
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// if cancel() is called, leave the loop early
if (isCancelled()) {
break;
}
}
// save the result
this.result = resultBuilder.toString();
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
// update progress here
}
// called after doInBackground finishes
protected void onPostExecute(Long result) {
//Log.v("API", this.result);
// put result into a json object
try {
JSONObject jsonObject = new JSONObject(this.result);
// call callback
listener.onTaskCompleted(jsonObject);
} catch (JSONException e) {
e.printStackTrace();
}
}
</code>
And this is interface for event
<code>
public interface OnTaskCompleted {
String onTaskCompleted(JSONObject result);
}
</code>
And this is class wrapped the DownloadTask
<code>
public class NativeApi implements OnTaskCompleted {
private DonwloadTask task;
public NativeApi(){
task= new DonwloadTask(this);
}
public void startDownload(String urlStr){
URL url= null;
try {
url = new URL(urlStr);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
#Override
public String onTaskCompleted(JSONObject result) {
return result.toString();
}
}
</code>
And javascript to call native code
<code>
function startDownload(url){
NativeApi.startDownload(url);
}
</code>
How can I subscribe onTaskCompleted in JavaScript?
You can make a call as follws:
MyActivity.activity.sendJavascript('yourFunction();');
Check this link for further info Calling javascript function from the android activity

How to wait for the child activity to finish

I am trying to make a phonegap/cordova plugin which is for converting speech to text using RecognizerIntent. The following is my code of the plugin class:
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
this.callbackContext = callbackContext;
try {
if (ACTION_INVOKE_SPEECH_RECOG.equals(action)) {
//JSONObject arg_object = args.getJSONObject(0);
Intent calIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
calIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, "en-US");
this.cordova.setActivityResultCallback(SpeechToTextPlugin.this);
this.cordova.getActivity().startActivityForResult(calIntent,REQUEST_CODE );
callbackContext.success("Completed Main Activity");
}
callbackContext.error("Invalid action");
return false;
} catch(Exception e) {
System.err.println("Exception: " + e.getMessage());
callbackContext.error(e.getMessage());
return false;
}
}
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (resultCode == Activity.RESULT_OK) {
JSONObject obj = new JSONObject();
try {
//obj.put("TEXT", intent.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS).toString());
callbackContext.success(intent.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS).toString());
}catch(JSONException e){
}
super.onActivityResult(requestCode, resultCode, intent);
}
}
I pass the recognized text to the javascript invoking the execute method. Right now, after making a call to startActivityForResult, the execute function returns back. How do I pass the recognized word to the js?
You have to use
sendJavascript("yourJSClass.yourJSMethod();");
or just
sendJavascript("yourJSMethod();");
Of course you will have to have:
yourJSMethod = function() {}
in your JS

GWT Native Method Warning

I'm doing a project in GWT to deploy in AppEngine and I'm getting a warning in Eclipse saying:
JavaScript parsing: Expected an identifier in JSNI
reference
Any ideas on what's causing this?
public void callFacebookAPI(String url) {
JsonpRequestBuilder requestBuilder = new JsonpRequestBuilder();
requestBuilder.requestObject(url, new AsyncCallback<FbUser>() {
public void onFailure(Throwable caught) {
System.out.println("FAIL" );
}
#Override
public void onSuccess(FbUser result) {
facebookUser = result;
System.out.println("Facebook name:" + facebookUser.getName());
}
});
}
private final native void doFbLoginFunction() /*-{
FB.login(function(response) {
if (response.authResponse) {
// connected
//return response.session;
var accessToken = response.accessToken;
var url = "http://graph.facebook.com/me?access_token=";
var facebookUrl = url + accessToken;
#com.google.gwt.smartpark.client.map.SmartPark::callFacebookAPI(Ljava/lang/String;Ljava/lang/
String;)(facebookUrl);
} else {
// cancelled
}
});
callFacebookAPI is not static so there must be something before the # in the reference in JSNI, e.g.
var that = this;
$wnd.FB.login($entry(function(response) {
// ...
that.#com.google.gwt.smartpark.client.map.SmartPack::callFacebookAPI(Ljava/lang/String;)(facebookUrl);
// ...
}));
Also, your callFacebookAPI takes a single argument, so the JSNI signature should have a single Ljava/lang/String;.

Categories

Resources