简体   繁体   English

kotlin-未调用javascript函数

[英]kotlin - javascript function is not being called

I'm building an android app in kotlin with the purpose of sendind user-defined parameters to a robot via JSON. 我正在kotlin中构建一个android应用,目的是通过JSON将用户定义的参数sendind传递给机器人。 In the side of the robot (which uses ROS) everything is set for receiving JSON objects. 在机器人的侧面(使用ROS),所有内容都已设置为接收JSON对象。 However, I'm still having a problem with the app: my app has an activity tasked with receiving the parameters, transform them to an appropiate data type (int or float) and send them to a javascript function which makes the connection with the robot's websocket server and publishes the parameters as a message to a ROS topic.the activity has other functions like resetting the parameters to their default values and going to other activities, but those functions work perfectly. 但是,我的应用程序仍然存在问题:我的应用程序有一个活动,任务是接收参数,将其转换为合适的数据类型(int或float),然后将其发送到javascript函数,该函数与机器人的websocket服务器并将这些参数作为消息发布到ROS主题。该活动具有其他功能,例如将参数重置为其默认值并转到其他活动,但是这些功能可以正常工作。

Here's the code of the activity: 这是活动的代码:

package com.example.jorge.autonavi3at

import android.content.Intent
import android.os.Build
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.annotation.RequiresApi
import android.support.v7.app.AlertDialog
import android.view.View
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.SeekBar
import kotlinx.android.synthetic.main.activity_triprobot.*

const val maxdef = 20
const val mindef = 4

class triprobot : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_triprobot)
        supportActionBar!!.setDisplayHomeAsUpEnabled(false)
        supportActionBar!!.setHomeButtonEnabled(false)
        robosender.webViewClient = roboBridge()
        robosender.settings.javaScriptEnabled = true
        robosender.loadUrl("file:///android_asset/rostalkerrobo.html")

        speedslider.progress = 20
        robospeed.text = speedslider.progress.toString()
        speedslider.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener{
            override fun onProgressChanged(seekbar: SeekBar?, progress: Int, fromUser: Boolean) {
                robospeed.setText(progress.toString())
            }

            override fun onStartTrackingTouch(seekbar: SeekBar?) {

            }

            override fun onStopTrackingTouch(seekbar: SeekBar?) {

            }
        })
        maxdist.setText(maxdef.toString())
        mindist.setText(mindef.toString())
        maxdist.setSelectAllOnFocus(true)
        mindist.setSelectAllOnFocus(true)

    }

    fun getRobParam(view: View){


        var paramerror = java.lang.Boolean.FALSE
        val speed = robospeed.text.toString()
        val tspeed = intconvert(speed)
        if (tspeed < 20 || tspeed > 100) {
            paramerror = java.lang.Boolean.TRUE
        }

        val dmax = maxdist.text.toString()
        val tdmax = intconvert(dmax)
        val dmin = mindist.text.toString()
        val tdmin = intconvert(dmin)
        if (tdmax < tdmin || tdmax > 20 || tdmin < 4 || tdmin > 10) {
            paramerror = java.lang.Boolean.TRUE
        }

        val imageh = imheight.text.toString()
        val timageh = intconvert(imageh)
        val imagew = imwidth.text.toString()
        val timagew = intconvert(imagew)
        val xc = centerx.text.toString()
        val txc = intconvert(xc)
        val yc = centery.text.toString()
        val tyc = intconvert(yc)
        val interior = intrad.text.toString()
        val tinterior = intconvert(interior)
        val exterior = extrad.text.toString()
        val texterior = intconvert(exterior)
        val mirror = ksi.text.toString()
        val tmirror = floatconvert(mirror)

        if (paramerror) {
            confirmError()
        } else {
            confirmParam(tspeed,tdmax,tdmin,timageh,timagew,txc,tyc,tinterior,texterior,tmirror) //This goes to JS call
        }
    }

    fun retmainfromrob(view: View) {
        // Do something in response to button
        val intent = Intent(this,tripconfig::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        startActivity(intent)

    }

    fun resetRobParam(view: View){
        speedslider.progress = 20
        maxdist.setText(maxdef.toString())
        mindist.setText(mindef.toString())
    }

    fun gotoApp(view: View){
        val intent = Intent(this,tripappli::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        startActivity(intent)
    }

    fun intconvert(convcase: String): Int {
        return if (convcase != "") {
            Integer.parseInt(convcase)
        } else {
            0
        }
    }

    fun floatconvert(convcase: String): Float {
        return if (convcase != "") {
            java.lang.Float.parseFloat(convcase)
        } else {
            0f
        }
    }

    fun confirmError() {
        val errorparam = ErrorDialogFragment()
        errorparam.show(supportFragmentManager, "bad_parameter")
    }

//Here is the JS call
    fun confirmParam(rspeed : Int,maxl : Int,minl : Int,iheight : Int,iwidth : Int,ppointx : Int, ppointy : Int, irad : Int, erad : Int, kagami : Float)  {
        goodparam.show(supportFragmentManager, "neat_parameter")*/
        val builder = AlertDialog.Builder(this)
        builder.setMessage(R.string.confirm_msg)
                .setTitle(R.string.confirm_param)
                .setPositiveButton(R.string.confirm_positive) { dialog, id ->
                    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
                        robosender.evaluateJavascript("robosend($rspeed, $minl, $maxl, $iheight, $iwidth, $ppointx, $ppointy, $irad, $erad, $kagami);", null)
                    } else {
                        robosender.loadUrl("javascript:robosend($rspeed, $minl, $maxl, $iheight, $iwidth, $ppointx, $ppointy, $irad, $erad, $kagami);")
                    }
                    val intent = Intent(this,tripconfig::class.java)
                    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
                    startActivity(intent)
                }.setNegativeButton(R.string.confirm_negative) {dialog, id ->

                }
        builder.show()
    }

    class roboBridge : WebViewClient(){
        @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
        override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
            view?.loadUrl(request?.url.toString())
            return true
        }
    }
}

The problem here lies in the javascript function calling. 这里的问题在于javascript函数调用。 It's simply not occurring. 这根本没有发生。

Here is the HTML code with the javascript function: 这是带有javascript函数的HTML代码:

<!DOCTYPE html>
<html>
<meta charset="utf-8" />
<script type="text/javascript" src="eventemitter2.js"></script>
<script type="text/javascript" src="roslib.js"></script>
<script type="text/javascript">

    var ros = new ROSLIB.Ros({
      url : 'ws://192.168.3.102:9090'
    });

    var harparam = new ROSLIB.topic({
      ros : ros,
      name : '/p3at_parameters',
      messageType : 'autonavi3at/roboParam',
      latch : true
    });

    function robosend(robovel, mindist, maxdist, imheight, imwidth, ppointx, ppointy, inrad, exrad, ksi){

      var rparam = new ROSLIB.message({
        speed : robovel,
        minrange : mindist,
        maxrange : maxdist,
        height: imheight,
        width : imwidth,
        inradius : inrad,
        exradius : exrad,
        cx : ppointx,
        cy : ppointy,
        mtype : ksi
      });

      harparam.publish(rparam);
    }
</script>
</html>

The conection to the websocket server occurs as the ROS console in the robot recognizes my mobile device as a client upon entering to this activity, but when I tap the button that would call the function, it just returns to the main activity without doing anything (using rostopic echo on the robot shows that no message was published). 进入websocket服务器的连接发生在机器人的ROS控制台在进入此活动时将我的移动设备识别为客户端的情况下,但是当我点击调用该函数的按钮时,它只是返回到主活动,而没有执行任何操作(在机器人上使用rostopic回声显示未发布任何消息)。

I tried to test the function by adding a return clause that would return a short message with one of the parameters sent, which would then be shown in the app as a toast, but the toast shows "null". 我试图通过添加一个return子句来测试该功能,该子句将返回一条带有已发送参数之一的短消息,然后将其在应用程序中显示为Toast,但Toast显示为“ null”。

Then, when I decided to make the message sending directly (no JS function, with some test values that matched the types defined for the message), the message was published. 然后,当我决定直接发送消息时(没有JS函数,某些测试值与为消息定义的类型相匹配),消息就发布了。

Is there a Way to solve this? 有办法解决吗?

Solved...it was a dumb mistake on my part. 解决了...这对我来说是一个愚蠢的错误。 Wrote topic and message without initial capital letters (Topic, Message)... 撰写主题和消息时不要使用大写字母(主题,消息)...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM