|
|
@@ -1,25 +1,36 @@
|
|
|
package com.yingyangfly.game.play
|
|
|
|
|
|
+import android.Manifest
|
|
|
import android.annotation.SuppressLint
|
|
|
import android.app.Activity
|
|
|
import android.app.ActivityManager
|
|
|
+import android.app.AlertDialog
|
|
|
import android.content.Context
|
|
|
import android.content.Intent
|
|
|
+import android.content.pm.PackageManager
|
|
|
import android.os.Build
|
|
|
import android.text.TextUtils
|
|
|
+import android.util.Log
|
|
|
import android.view.MotionEvent
|
|
|
import android.view.View
|
|
|
import android.view.ViewTreeObserver
|
|
|
+import android.webkit.ConsoleMessage
|
|
|
+import android.webkit.PermissionRequest
|
|
|
+import android.webkit.WebChromeClient
|
|
|
import android.webkit.WebResourceRequest
|
|
|
import android.webkit.WebSettings
|
|
|
import android.webkit.WebView
|
|
|
import android.webkit.WebViewClient
|
|
|
import android.widget.FrameLayout
|
|
|
+import android.widget.Toast
|
|
|
import androidx.constraintlayout.widget.ConstraintLayout
|
|
|
import androidx.constraintlayout.widget.ConstraintSet
|
|
|
+import androidx.core.app.ActivityCompat
|
|
|
+import androidx.core.content.ContextCompat
|
|
|
import com.alibaba.android.arouter.facade.annotation.Route
|
|
|
import com.alibaba.android.arouter.launcher.ARouter
|
|
|
import com.bumptech.glide.Glide
|
|
|
+import com.tencent.qcloud.tuikit.tuichat.TUIChatService.TAG
|
|
|
import com.yingyangfly.baselib.bean.GameDataBean
|
|
|
import com.yingyangfly.baselib.bean.GetSaveGameRecordBean
|
|
|
import com.yingyangfly.baselib.db.VoicePlayerBean
|
|
|
@@ -100,6 +111,15 @@ class PlayGameActivity : BaseMVVMActivity<ActivityPlayGameBinding, PlayGameViewM
|
|
|
private var twoStep = ""
|
|
|
private var threeStep = ""
|
|
|
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 麦克风
|
|
|
+ */
|
|
|
+ private var pendingPermissionRequest: PermissionRequest? = null
|
|
|
+ companion object {
|
|
|
+ private const val PERMISSION_REQUEST_CODE_MIC = 100
|
|
|
+ }
|
|
|
+
|
|
|
override fun initViews() {
|
|
|
id = intent.getStringExtra("id") ?: ""
|
|
|
gameCode = intent.getStringExtra("gameCode") ?: ""
|
|
|
@@ -137,6 +157,7 @@ class PlayGameActivity : BaseMVVMActivity<ActivityPlayGameBinding, PlayGameViewM
|
|
|
mConstrainSet_one?.clone(binding.gameParentLayout)
|
|
|
}
|
|
|
|
|
|
+
|
|
|
@SuppressLint("ClickableViewAccessibility")
|
|
|
override fun initListener() {
|
|
|
binding {
|
|
|
@@ -264,9 +285,140 @@ class PlayGameActivity : BaseMVVMActivity<ActivityPlayGameBinding, PlayGameViewM
|
|
|
super.onPageFinished(view, url)
|
|
|
}
|
|
|
}
|
|
|
+ binding.webView.setFocusable(true);
|
|
|
+ binding.webView.setFocusableInTouchMode(true);
|
|
|
+ binding.webView.requestFocus(); // 让 WebView 自身获得焦点
|
|
|
+ // WebChromeClient 处理权限请求(麦克风/摄像头)
|
|
|
+ binding.webView.webChromeClient = object : WebChromeClient() {
|
|
|
+ override fun onPermissionRequest(request: PermissionRequest) {
|
|
|
+ Log.d(TAG, "收到权限请求: ${request.resources.joinToString()}")
|
|
|
+
|
|
|
+ val resources = request.resources
|
|
|
+ val hasAudioRequest = resources.contains(PermissionRequest.RESOURCE_AUDIO_CAPTURE)
|
|
|
+
|
|
|
+ if (hasAudioRequest) {
|
|
|
+ // 检查是否已有权限
|
|
|
+ val hasPermission = ContextCompat.checkSelfPermission(
|
|
|
+ this@PlayGameActivity,
|
|
|
+ Manifest.permission.RECORD_AUDIO
|
|
|
+ ) == PackageManager.PERMISSION_GRANTED
|
|
|
+
|
|
|
+ if (hasPermission) {
|
|
|
+ // 已经有权限,直接授予
|
|
|
+ request.grant(arrayOf(PermissionRequest.RESOURCE_AUDIO_CAPTURE))
|
|
|
+ Log.d(TAG, "已有权限,直接授予WebView")
|
|
|
+ } else {
|
|
|
+ // 保存请求,先请求系统权限
|
|
|
+ pendingPermissionRequest = request
|
|
|
+
|
|
|
+ // 检查是否需要显示权限说明
|
|
|
+ if (shouldShowRequestPermissionRationale(Manifest.permission.RECORD_AUDIO)) {
|
|
|
+ // 显示说明
|
|
|
+ showPermissionRationaleDialog()
|
|
|
+ } else {
|
|
|
+ // 直接请求权限
|
|
|
+ requestSystemAudioPermission()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 拒绝其他权限请求
|
|
|
+ request.deny()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onPermissionRequestCanceled(request: PermissionRequest) {
|
|
|
+ super.onPermissionRequestCanceled(request)
|
|
|
+ Log.d(TAG, "权限请求被取消")
|
|
|
+ if (pendingPermissionRequest === request) {
|
|
|
+ pendingPermissionRequest = null
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理控制台日志
|
|
|
+ override fun onConsoleMessage(consoleMessage: ConsoleMessage?): Boolean {
|
|
|
+ consoleMessage?.let {
|
|
|
+ Log.d("WebViewConsole",
|
|
|
+ "${it.messageLevel()}: ${it.message()} at ${it.sourceId()}:${it.lineNumber()}")
|
|
|
+ }
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
binding.webView.loadUrl(gameUrl)
|
|
|
}
|
|
|
|
|
|
+ private fun showPermissionRationaleDialog() {
|
|
|
+ AlertDialog.Builder(this)
|
|
|
+ .setTitle("需要麦克风权限")
|
|
|
+ .setMessage("录音功能需要使用麦克风,请允许权限")
|
|
|
+ .setPositiveButton("允许") { dialog, which ->
|
|
|
+ requestSystemAudioPermission()
|
|
|
+ }
|
|
|
+ .setNegativeButton("取消") { dialog, which ->
|
|
|
+ pendingPermissionRequest?.deny()
|
|
|
+ pendingPermissionRequest = null
|
|
|
+ }
|
|
|
+ .setOnCancelListener {
|
|
|
+ pendingPermissionRequest?.deny()
|
|
|
+ pendingPermissionRequest = null
|
|
|
+ }
|
|
|
+ .show()
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun requestSystemAudioPermission() {
|
|
|
+ ActivityCompat.requestPermissions(
|
|
|
+ this,
|
|
|
+ arrayOf(Manifest.permission.RECORD_AUDIO),
|
|
|
+ PERMISSION_REQUEST_CODE_MIC
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ override fun onRequestPermissionsResult(
|
|
|
+ requestCode: Int,
|
|
|
+ permissions: Array<String>,
|
|
|
+ grantResults: IntArray
|
|
|
+ ) {
|
|
|
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
|
|
+
|
|
|
+ if (requestCode == PERMISSION_REQUEST_CODE_MIC) {
|
|
|
+ if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
|
|
+ Log.d(TAG, "用户授予了麦克风权限")
|
|
|
+
|
|
|
+ // 授予WebView权限
|
|
|
+ pendingPermissionRequest?.grant(arrayOf(PermissionRequest.RESOURCE_AUDIO_CAPTURE))
|
|
|
+ Toast.makeText(this, "麦克风权限已授予", Toast.LENGTH_SHORT).show()
|
|
|
+ } else {
|
|
|
+ Log.d(TAG, "用户拒绝了麦克风权限")
|
|
|
+
|
|
|
+ // 拒绝WebView权限
|
|
|
+ pendingPermissionRequest?.deny()
|
|
|
+
|
|
|
+ // 检查是否永久拒绝
|
|
|
+ if (!shouldShowRequestPermissionRationale(Manifest.permission.RECORD_AUDIO)) {
|
|
|
+ // 永久拒绝,引导用户去设置
|
|
|
+ showGoToSettingsDialog()
|
|
|
+ } else {
|
|
|
+ Toast.makeText(this, "需要麦克风权限才能录音", Toast.LENGTH_SHORT).show()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ pendingPermissionRequest = null
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private fun showGoToSettingsDialog() {
|
|
|
+ AlertDialog.Builder(this)
|
|
|
+ .setTitle("需要麦克风权限")
|
|
|
+ .setMessage("您已永久拒绝麦克风权限,请在设置中开启")
|
|
|
+ .setPositiveButton("去设置") { dialog, which ->
|
|
|
+// openAppSettings()
|
|
|
+ }
|
|
|
+ .setNegativeButton("取消", null)
|
|
|
+ .show()
|
|
|
+ }
|
|
|
+
|
|
|
@SuppressLint("ClickableViewAccessibility")
|
|
|
override fun onTouch(v: View, event: MotionEvent): Boolean {
|
|
|
when (event.action) {
|