我在kotlin中构建一个Android应用程序,目的是通过JSON将sendind用户定义的参数发送给机器人。在机器人(使用ROS)的一侧,一切都被设置为接收JSON对象。但是,我仍然对应用程序有问题:我的应用程序有一个活动,负责接收参数,将它们转换为适当的数据类型(int或float)并将它们发送到与之建立连接的javascript函数机器人的websocket服务器并将参数作为消息发布到ROS主题。该活动还有其他功能,如将参数重置为默认值并转到其他活动,但这些功能完美无缺。
以下是活动代码:
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
}
}
}
这里的问题在于javascript函数调用。它根本没有发生。
以下是带有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>
对于websocket服务器的连接发生在机器人中的ROS控制台在进入此活动时将我的移动设备识别为客户端时,但是当我点击将调用该功能的按钮时,它只返回到主活动而没有做任何事情(在机器人上使用rostopic echo表示没有发布消息)。
我尝试通过添加一个return子句来测试该函数,该子句将返回一条带有其中一个参数的短消息,然后将其作为toast显示在应用程序中,但是toast显示&#34; null&#34 ;
然后,当我决定直接发送消息时(没有JS函数,其中一些测试值与为消息定义的类型相匹配),消息已发布。
有没有办法解决这个问题?
答案 0 :(得分:0)
解决了......对我来说这是一个愚蠢的错误。写了主题和消息,没有首字母大写字母(主题,消息)......