树莓派小车3——安卓客户端

2022-07-30,,

 项目地址 https://github.com/ffmydream/WiCar

界面做的很难看,美工方面实在不在行。

重点是按钮触摸事件的处理,这里搬了RepeatListener项目代码,例如:

       leftButton.setOnTouchListener(
            RepeatListener(300, 300, //两个参数,第一个参数:首次响应延时,即第一次响应和第二次响应的间隔时间,第二个参数:从第二次响应后,以后每次响应间隔时间
                View.OnClickListener {
                    CoroutineScope(Dispatchers.IO).launch { 
                        ch.send("car:left:100:")
                    }
                })
        )

 为左转按钮绑定监听,检测到左转按钮被按下,每隔300ms,持续发送"car:left:100:"给另一个socket协程。

        CoroutineScope(Dispatchers.IO).launch {

            try {
                val os = Socket("192.168.1.166", 50000).getOutputStream()
                val pw = PrintWriter(os)
                while (true) {
                    pw.write(ch.receive())
                    pw.flush()
                }
            } catch (e: Exception) {
            } finally {

            }
        }

上面这个是和socket通信,没有数据发送的时候,协程被挂起在ch.receive(),接收到数据,使用pw.write发送到tcp服务器

 

 

 

package com.example.wicar

import android.annotation.SuppressLint
import android.content.pm.ActivityInfo
import android.os.Bundle
import android.util.Log
import android.view.View
import android.webkit.WebChromeClient
import android.webkit.WebSettings
import android.webkit.WebViewClient
import android.widget.CompoundButton
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import java.io.PrintWriter
import java.net.Socket

object SrvAngle {
    var hSrvAngle = 90
    var vSrvAngle = 90
}

class MainActivity : AppCompatActivity() {
    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val ch = Channel<String>(0)

        webView.settings.apply {
            javaScriptEnabled = true
            javaScriptCanOpenWindowsAutomatically = true
            allowFileAccess = true // 设置允许访问文件数据
            setSupportZoom(false)
            builtInZoomControls = true
            cacheMode = WebSettings.LOAD_CACHE_ELSE_NETWORK
            domStorageEnabled = true
            databaseEnabled = true
            useWideViewPort = true
            loadWithOverviewMode = true
        }
        webView.webChromeClient = WebChromeClient()
        webView.loadUrl("http://192.168.1.166:8081/")
        camSwitch.setOnCheckedChangeListener { _, isChecked ->
            CoroutineScope(Dispatchers.IO).launch {
                if (isChecked) {
                    ch.send("cmd:sudo motion:0:")
                } else {
                    ch.send("cmd:sudo pkill -KILL motion:0:")
                }
            }
        }

        CoroutineScope(Dispatchers.IO).launch {

            try {
                val os = Socket("192.168.1.166", 50000).getOutputStream()
                val pw = PrintWriter(os)
                while (true) {
                    pw.write(ch.receive())
                    pw.flush()
                }
            } catch (e: Exception) {
            } finally {

            }
        }

        leftButton.setOnTouchListener(
            RepeatListener(300, 300,
                View.OnClickListener {
                    CoroutineScope(Dispatchers.IO).launch {
                        ch.send("car:left:100:")
                    }
                })
        )

        rightButton.setOnTouchListener(
            RepeatListener(300, 300,
                View.OnClickListener {
                    CoroutineScope(Dispatchers.IO).launch {
                        ch.send("car:right:100:")
                    }
                })
        )
        forButton.setOnTouchListener(
            RepeatListener(300, 300,
                View.OnClickListener {
                    CoroutineScope(Dispatchers.IO).launch {
                        ch.send("car:for:100:")
                    }
                })
        )
        backButton.setOnTouchListener(
            RepeatListener(300, 300,
                View.OnClickListener {
                    CoroutineScope(Dispatchers.IO).launch {
                        ch.send("car:back:100:")
                    }
                })
        )
        srvLeftButton.setOnTouchListener(
            RepeatListener(300, 50,
                View.OnClickListener {
                    CoroutineScope(Dispatchers.IO).launch {
                        if (SrvAngle.hSrvAngle > 3)
                            SrvAngle.hSrvAngle = SrvAngle.hSrvAngle - 2
                        ch.send("srvo:horiz:${SrvAngle.hSrvAngle}:")
                        delay(5)
                    }
                })
        )
        srvRightButton.setOnTouchListener(
            RepeatListener(300, 50,
                View.OnClickListener {
                    CoroutineScope(Dispatchers.IO).launch {
                        if (SrvAngle.hSrvAngle < 177)
                            SrvAngle.hSrvAngle = SrvAngle.hSrvAngle + 2
                        ch.send("srvo:horiz:${SrvAngle.hSrvAngle}:")
                        delay(5)
                    }
                })
        )
        srvUpButton.setOnTouchListener(
            RepeatListener(300, 50,
                View.OnClickListener {
                    CoroutineScope(Dispatchers.IO).launch {
                        if (SrvAngle.vSrvAngle < 170)
                            SrvAngle.vSrvAngle = SrvAngle.vSrvAngle + 2
                        ch.send("srvo:vertic:${SrvAngle.vSrvAngle}:")
                        delay(5)
                    }
                })
        )
        srvDownButton.setOnTouchListener(
            RepeatListener(300, 50,
                View.OnClickListener {
                    CoroutineScope(Dispatchers.IO).launch {
                        if (SrvAngle.vSrvAngle > 60)
                            SrvAngle.vSrvAngle = SrvAngle.vSrvAngle - 2
                        ch.send("srvo:vertic:${SrvAngle.vSrvAngle}:")
                        delay(5)
                    }
                })
        )
        srvInitButton.setOnClickListener() {
            CoroutineScope(Dispatchers.IO).launch {
                ch.send("srv:init:0:")
            }
        }
    }

}

 

本文地址:https://blog.csdn.net/ffmydream/article/details/108140128

《树莓派小车3——安卓客户端.doc》

下载本文的Word格式文档,以方便收藏与打印。