物理按键
This commit is contained in:
parent
5190f5d489
commit
4d12f780ea
Binary file not shown.
|
|
@ -52,7 +52,7 @@ public class pttActivity extends AppCompatActivity {
|
|||
findViewById(R.id.login).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
SendAtUtil.toLogin("gzzdweb01", "123456", "61.243.1.123", 1, 1);
|
||||
SendAtUtil.toLogin("admin", "poc123456", "220.154.131.231", 1, 1);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -131,17 +131,25 @@ class LoginActivity : AppCompatActivity() {
|
|||
|
||||
Toast.makeText(this@LoginActivity, "登录成功", Toast.LENGTH_SHORT).show()
|
||||
|
||||
// 1. 确保 PTT 引擎已初始化并登录
|
||||
try {
|
||||
// 确保 PTT 引擎已初始化
|
||||
com.example.kingway.ptt.MyApplication.init(this@LoginActivity)
|
||||
// 异步初始化 PTT 登录 (区分 Android 业务登录)
|
||||
com.example.kingway.ptt.SendAtUtil.toLogin("gzzdweb01", "123456", "61.243.1.123", 1, 1)
|
||||
} catch (e: Exception) {
|
||||
Timber.tag("Login").e(e, "检查更新失败")
|
||||
Timber.tag("PTT").e(e, "PTT init error")
|
||||
}
|
||||
|
||||
// 初始化打印机 (异步)
|
||||
// 2. 启动硬件 GPIO 监听
|
||||
try {
|
||||
com.stand.standapp.utils.GpioManager.init(this@LoginActivity)
|
||||
com.stand.standapp.utils.GpioManager.startListening()
|
||||
} catch (e: Exception) {
|
||||
Timber.tag("GPIO").e(e, "GPIO init error")
|
||||
}
|
||||
|
||||
// 3. 初始化打印机 (异步)
|
||||
PrinterManager.init(this@LoginActivity)
|
||||
|
||||
startActivity(Intent(this@LoginActivity, MainActivity::class.java))
|
||||
|
|
@ -150,6 +158,7 @@ class LoginActivity : AppCompatActivity() {
|
|||
val msg = json.optString("msg", "登录失败")
|
||||
Toast.makeText(this@LoginActivity, msg, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
Timber.tag("Login").e(e, "解析响应失败")
|
||||
Toast.makeText(this@LoginActivity, "服务器响应异常", Toast.LENGTH_SHORT).show()
|
||||
|
|
|
|||
|
|
@ -37,9 +37,31 @@ class MainActivity : AppCompatActivity() {
|
|||
Timber.tag("MainActivity").d("onPttLoginSuccess called from Native")
|
||||
executeJs("onPttLoginSuccess")
|
||||
}
|
||||
|
||||
// 硬件按键触发
|
||||
@JvmStatic
|
||||
fun onHardwarePttDown() {
|
||||
instance?.runOnUiThread {
|
||||
// 直接调用 JSBridge 对象的逻辑以复用保护机制
|
||||
val jsInterface = instance?.mAgentWeb?.webCreator?.webView?.tag as? AndroidInterface
|
||||
// 或者更直接一点,我们把逻辑抽离出来
|
||||
instance?.pttInterface?.pttSpeakPlay()
|
||||
// 通知 H5 更新 UI
|
||||
executeJs("onHardwarePttDown")
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onHardwarePttUp() {
|
||||
instance?.runOnUiThread {
|
||||
instance?.pttInterface?.pttSpeakRelease()
|
||||
executeJs("onHardwarePttUp")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var mAgentWeb: AgentWeb? = null
|
||||
private var pttInterface: AndroidInterface? = null
|
||||
|
||||
private val mHandler = android.os.Handler(android.os.Looper.getMainLooper())
|
||||
private val TIMEOUT_MS = 30000L
|
||||
|
|
@ -79,21 +101,11 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
})
|
||||
.setWebViewClient(object : WebViewClient() {
|
||||
override fun onPageFinished(view: WebView?, url: String?) {
|
||||
super.onPageFinished(view, url)
|
||||
cancelTimeoutTimer()
|
||||
}
|
||||
|
||||
override fun onReceivedError(view: WebView?, request: WebResourceRequest?, error: WebResourceError?) {
|
||||
Timber.tag("WebError").e("URL: ${request?.url}, Error: ${error?.description} (Code: ${error?.errorCode})")
|
||||
if (request?.isForMainFrame == true) {
|
||||
showErrorPage()
|
||||
}
|
||||
super.onReceivedError(view, request, error)
|
||||
}
|
||||
// ...
|
||||
})
|
||||
.addJavascriptInterface("android", AndroidInterface(this))
|
||||
.addJavascriptInterface("android", AndroidInterface(this).also { pttInterface = it })
|
||||
.createAgentWeb()
|
||||
|
||||
.ready()
|
||||
.go(finalUrl)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,102 @@
|
|||
package com.stand.standapp.utils
|
||||
|
||||
import android.app.ZysjSystemManager
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.stand.standapp.MainActivity
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* 硬件 GPIO 监听管理类 (用于物理 PTT 按键)
|
||||
*/
|
||||
object GpioManager {
|
||||
private var mZysjSystemManager: ZysjSystemManager? = null
|
||||
private var mIsRunning = false
|
||||
private var mThread: Thread? = null
|
||||
private var lastGpioValue = 1 // 默认松开状态 (1)
|
||||
|
||||
fun init(context: Context) {
|
||||
if (mZysjSystemManager != null) return
|
||||
try {
|
||||
mZysjSystemManager = context.applicationContext.getSystemService("zysj") as? ZysjSystemManager
|
||||
Timber.tag("GPIO").i("ZysjSystemManager initialized: ${mZysjSystemManager != null}")
|
||||
} catch (e: Exception) {
|
||||
Timber.tag("GPIO").e(e, "Failed to get ZysjSystemManager")
|
||||
}
|
||||
}
|
||||
|
||||
fun startListening() {
|
||||
if (mIsRunning) return
|
||||
mIsRunning = true
|
||||
mThread = Thread {
|
||||
Timber.tag("GPIO").i("Start GPIO listening thread")
|
||||
while (mIsRunning) {
|
||||
try {
|
||||
// 硬件轮询频率优化:50ms 既能保证响应速度,又能降低 CPU 消耗
|
||||
Thread.sleep(50)
|
||||
val manager = mZysjSystemManager ?: continue
|
||||
|
||||
// 获取 GPIO 1 的值 (0 按下, 1 松开)
|
||||
val currentValue = manager.get_zysj_gpio_value(1)
|
||||
|
||||
if (currentValue != lastGpioValue) {
|
||||
Timber.tag("GPIO").d("GPIO 1 Value changed: $lastGpioValue -> $currentValue")
|
||||
handleGpioChange(currentValue)
|
||||
lastGpioValue = currentValue
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.tag("GPIO").e(e, "Error in GPIO loop")
|
||||
}
|
||||
}
|
||||
}.apply { start() }
|
||||
}
|
||||
|
||||
fun stopListening() {
|
||||
mIsRunning = false
|
||||
mThread = null
|
||||
}
|
||||
|
||||
private var isSpeaking = false
|
||||
private var lastSpeakTime = 0L
|
||||
private val MIN_SPEAK_DURATION = 200L
|
||||
|
||||
private fun handleGpioChange(value: Int) {
|
||||
// 切换到主线程处理逻辑,确保线程安全且方便使用 Handler
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
if (value == 0) {
|
||||
// 硬件按下 PTT
|
||||
if (!isSpeaking) {
|
||||
isSpeaking = true
|
||||
lastSpeakTime = System.currentTimeMillis()
|
||||
com.example.kingway.ptt.SendAtUtil.speakPlay()
|
||||
Timber.tag("GPIO").d("PTT Speak Play (Hardware)")
|
||||
}
|
||||
} else {
|
||||
// 硬件松开 PTT
|
||||
if (isSpeaking) {
|
||||
val now = System.currentTimeMillis()
|
||||
val duration = now - lastSpeakTime
|
||||
|
||||
if (duration < MIN_SPEAK_DURATION) {
|
||||
val delay = MIN_SPEAK_DURATION - duration
|
||||
Timber.tag("GPIO").d("Hardware speak duration too short ($duration ms), delaying release by $delay ms")
|
||||
Handler(Looper.getMainLooper()).postDelayed({
|
||||
realRelease()
|
||||
}, delay)
|
||||
} else {
|
||||
realRelease()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun realRelease() {
|
||||
if (isSpeaking) {
|
||||
isSpeaking = false
|
||||
com.example.kingway.ptt.SendAtUtil.speakRelease()
|
||||
Timber.tag("GPIO").d("PTT Speak Release (Hardware)")
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue