物理按键
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() {
|
findViewById(R.id.login).setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
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()
|
Toast.makeText(this@LoginActivity, "登录成功", Toast.LENGTH_SHORT).show()
|
||||||
|
|
||||||
|
// 1. 确保 PTT 引擎已初始化并登录
|
||||||
try {
|
try {
|
||||||
// 确保 PTT 引擎已初始化
|
// 确保 PTT 引擎已初始化
|
||||||
com.example.kingway.ptt.MyApplication.init(this@LoginActivity)
|
com.example.kingway.ptt.MyApplication.init(this@LoginActivity)
|
||||||
// 异步初始化 PTT 登录 (区分 Android 业务登录)
|
// 异步初始化 PTT 登录 (区分 Android 业务登录)
|
||||||
com.example.kingway.ptt.SendAtUtil.toLogin("gzzdweb01", "123456", "61.243.1.123", 1, 1)
|
com.example.kingway.ptt.SendAtUtil.toLogin("gzzdweb01", "123456", "61.243.1.123", 1, 1)
|
||||||
} catch (e: Exception) {
|
} 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)
|
PrinterManager.init(this@LoginActivity)
|
||||||
|
|
||||||
startActivity(Intent(this@LoginActivity, MainActivity::class.java))
|
startActivity(Intent(this@LoginActivity, MainActivity::class.java))
|
||||||
|
|
@ -150,6 +158,7 @@ class LoginActivity : AppCompatActivity() {
|
||||||
val msg = json.optString("msg", "登录失败")
|
val msg = json.optString("msg", "登录失败")
|
||||||
Toast.makeText(this@LoginActivity, msg, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@LoginActivity, msg, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Timber.tag("Login").e(e, "解析响应失败")
|
Timber.tag("Login").e(e, "解析响应失败")
|
||||||
Toast.makeText(this@LoginActivity, "服务器响应异常", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@LoginActivity, "服务器响应异常", Toast.LENGTH_SHORT).show()
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,31 @@ class MainActivity : AppCompatActivity() {
|
||||||
Timber.tag("MainActivity").d("onPttLoginSuccess called from Native")
|
Timber.tag("MainActivity").d("onPttLoginSuccess called from Native")
|
||||||
executeJs("onPttLoginSuccess")
|
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 mAgentWeb: AgentWeb? = null
|
||||||
|
private var pttInterface: AndroidInterface? = null
|
||||||
|
|
||||||
private val mHandler = android.os.Handler(android.os.Looper.getMainLooper())
|
private val mHandler = android.os.Handler(android.os.Looper.getMainLooper())
|
||||||
private val TIMEOUT_MS = 30000L
|
private val TIMEOUT_MS = 30000L
|
||||||
|
|
@ -79,21 +101,11 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.setWebViewClient(object : WebViewClient() {
|
.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()
|
.createAgentWeb()
|
||||||
|
|
||||||
.ready()
|
.ready()
|
||||||
.go(finalUrl)
|
.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