Blockly Android - Call Java code from custom Block

460 views
Skip to first unread message

Jorge gusa

unread,
Apr 20, 2017, 4:14:11 PM4/20/17
to Blockly
Hello:

I am trying to generate js code that calls native Java-Android code. I am able to generate custom blocks and run js code, however the problem appear when I try to call native code.

I know that for calling native js code I have to access the webview and call

webView.addJavascriptInterface(jsShowToast, "AndroidFunction");

The problem here is that CodeGeneratorService object is using its own webview that I can´t access it. I am getting an error from this
object when I try to generate js code.

The question is how to get the webview from CodegeneratorService object?

Kind regards.

Andrew n marshall

unread,
Apr 20, 2017, 4:22:28 PM4/20/17
to blo...@googlegroups.com
We do not currently support direct access to the WebView where the generators run. We expect the code to generate rather hermetically (without additional inputs or side effects) and expect developers to run the generated code in a different WebView.

Can you give us a better idea about the use case for adding a native hook into the code generation pipeline.

--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jorge

unread,
Apr 21, 2017, 2:10:01 AM4/21/17
to blo...@googlegroups.com
Hello,

Thank you very much for your answer.

I am able to run the code in a diferent webview. That is ok. The problem appears when I want to run java code from js. As you the code generator checks the code integrity it is not able to find the functions I have created using addJavascrpitInterface.
The use case is simple, I want to have access to the phone native functionalities like acelerometer, gps, bluetooth, wifi and so on. For example:
  1. I would like to create a block that beeps when it runs.
  2. Block that get the phone position based on acelerometer, to use the phone as a gamepad.
  3. I would like to get/send data via bluetooth
  4. I would like to get info from the GPS or camera, for example.

It could be possible adding js-java interface, however I would need access to the webview that generate the code to add the javascript interface.

Thank you very much and kind regards.



Jorge



--
You received this message because you are subscribed to a topic in the Google Groups "Blockly" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/blockly/MyP2YfgoVM0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to blockly+unsubscribe@googlegroups.com.

Andrew n marshall

unread,
Apr 21, 2017, 2:21:37 AM4/21/17
to blo...@googlegroups.com
Okay, so this is not about running native Java with the generators.

I don't know what you mean by "checks the code integrity". The generators are not comparing against any known list of functions. What you are suggesting is perfectly acceptable without modifying the generator WebView.

You will need to add a block for any function you want to call, whether that is JavaScript or JavascriptInterface. Then, you'll add a generator function for that block that outputs the desired function call as a code string. With this, should find your call in the code string and it should be runnable in your own WebView.

Look at the Turtle blocks and generators as an example.

Erik Pasternak

unread,
Apr 21, 2017, 4:14:07 PM4/21/17
to Blockly
Hi Jorge,

The generator should just be returning a String with the generated code. By default it doesn't evaluated it or do any validation. When you pass that string to your 2nd WebView you'll need a script to wrap it that calls eval() or similar on the text.

Also, have you been able to run code you've written yourself in JS to double check you've got the JavascriptInterface working correctly without the generator? If so, for the next step I'd suggest logging the exact code that's being run in your 2nd webview to check that there's no syntax error or other problems in the generated code. You can also try adding "console.log('<method name> running');\n" to each of your generators to see if they're being run.

There can also be some trickiness with passing strings to a WebView. If you look at the CodeGeneratorService you can borrow some of the code to make sure everything's getting escaped correctly when you pass it to your own WebView.

Let us know if you have specific errors in the console that could help figure out what's going wrong.

Cheers,
Erik

Jorge



To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to a topic in the Google Groups "Blockly" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/blockly/MyP2YfgoVM0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to blockly+u...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.

Jorge

unread,
Apr 24, 2017, 4:10:09 PM4/24/17
to blo...@googlegroups.com
Hi:

Thank you very much for your fast answer. If it dosen´t evaluate the code or do any comprobation why I am getting this error?

0 I/chromium: [INFO:CONSOLE(67)] "ReferenceError: AndroidFunction is not defined
             at Blockly.Block.Blockly.JavaScript.play_sound (file:///android_asset/blockly/CodeGenerator.js:24:6)
             at Blockly.Generator.blockToCode (file:///android_asset/blockly_compressed.js:1384:268)
             at Blockly.Generator.workspaceToCode (file:///android_asset/blockly_compressed.js:1382:246)
             at generate (file:///android_asset/background_compiler.html:64:39)
             at <anonymous>:1:1", source: file:///android_asset/background_compiler.html


I am using this generator. And I am just printing the generated code using CodeGeneratorCallback. Of course I don´t see any generated code at all.

Blockly.JavaScript['play_sound'] = function(block) {
    var value = block.getFieldValue('SOUNDFILE');
     AndroidFunction.showToast('JAVA JS INTERFACE EXAMPLE');
};

And Android function is what is not located. This will be added later on with:
webView.addJavascriptInterface(jsShowToast, "AndroidFunction");
Thank you very much.

Jorge



To unsubscribe from this group and all its topics, send an email to blockly+unsubscribe@googlegroups.com.

Erik Pasternak

unread,
Apr 24, 2017, 4:30:12 PM4/24/17
to Blockly
Hi Jorge,

Your generator should not be calling anything directly. It should return a string of code for your 2nd webview to run. The string returned by your generator is the code that gets passed over to your runtime which then evaluates it as code.

Eg:

Blockly.JavaScript['play_sound'] = function(block) {
    var value = block.getFieldValue('SOUNDFILE');
    return 'AndroidFunction.showToast(\'JAVA JS INTERFACE EXAMPLE: sound file was ' + value + '\');'
};
--
Erik Pasternak | Master of the House | epas...@google.com     

Andrew n marshall

unread,
Apr 24, 2017, 7:41:45 PM4/24/17
to blo...@googlegroups.com
Jorge,
The Blockly.JavaScript[ ] is the code generator. It should return the JavaScript code string for your call, not call it directly.

// Approximately from memory...
Blockly.JavaScript['play_sound'] = function(block) {
    var value = block.getFieldValue('SOUNDFILE');
    return 'playSound(\''+value+'\');'
};

This code should later be run in your own WebView, where you would have attached the native function.



To unsubscribe from this group and stop receiving emails from it, send an email to blockly+unsubscribe@googlegroups.com.

Jorge

unread,
Apr 30, 2017, 8:59:30 AM4/30/17
to blo...@googlegroups.com
Thank you very much for your help. It is working like a charm. I have beeing doing wrongly.

Regards.

Jorge


Reply all
Reply to author
Forward
0 new messages