217 lines
7.9 KiB
Kotlin
217 lines
7.9 KiB
Kotlin
package com.xyzshell.myphoneinfo.dialog
|
||
|
||
import android.annotation.SuppressLint
|
||
import android.os.Bundle
|
||
import android.os.CountDownTimer
|
||
import android.view.LayoutInflater
|
||
import android.view.View
|
||
import android.view.ViewGroup
|
||
import android.widget.TextView
|
||
import android.widget.Toast
|
||
import androidx.compose.material3.Text
|
||
import com.xyzshell.andinfo.AndInfo
|
||
import com.xyzshell.andinfo.libs.DeviceInfo
|
||
import com.xyzshell.myphoneinfo.R
|
||
import com.xyzshell.myphoneinfo.base.BaseDialogFragment
|
||
import com.xyzshell.myphoneinfo.databinding.DialogBlueToothBinding
|
||
|
||
class DialogBlueTooth(val type:Int) :BaseDialogFragment<DialogBlueToothBinding>(DialogBlueToothBinding::inflate){
|
||
private var isScanning = false
|
||
private var scanTimer: CountDownTimer? = null
|
||
private val SCAN_DURATION = 15000 // 15秒
|
||
override fun getTitle(): String = resources.getString(R.string.bluetooth)
|
||
|
||
override fun getIconRes(): Int=5
|
||
|
||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||
super.onViewCreated(view, savedInstanceState)
|
||
val bluetoothInfo = AndInfo.instance.bluetooth
|
||
val list= bluetoothInfo.getBondedDevicesInfo()
|
||
|
||
// ArrayList<Map<String, String>>()
|
||
// bluetoothInfo.bondedDevices.forEach { (name, address) ->
|
||
// val deviceMap = mapOf(
|
||
// "name" to (name ?: "Unknown device"),
|
||
// "address" to (address ?: "")
|
||
// )
|
||
// list.add(deviceMap)
|
||
// }
|
||
if(type==0){// 显示已配对设备列表
|
||
binding.progressbar.visibility=View.GONE
|
||
val container = binding.view as? ViewGroup
|
||
container?.let {
|
||
// 遍历 list,为每个设备创建 item view
|
||
if(list.isEmpty()){
|
||
it.addView(TextView(requireContext()).apply {
|
||
text = getString(R.string.no_devices)
|
||
})
|
||
}else{
|
||
list.forEach { deviceMap ->
|
||
// 加载 item 布局
|
||
val itemView = LayoutInflater.from(requireContext())
|
||
.inflate(R.layout.item_blue_tooth, it, false)
|
||
|
||
// 设置设备信息
|
||
val tvName = itemView.findViewById<TextView>(R.id.textTitle)
|
||
val tvAddress = itemView.findViewById<TextView>(R.id.textContent)
|
||
|
||
tvName.text = deviceMap.name
|
||
tvAddress.text = deviceMap.address
|
||
// 添加到容器
|
||
it.addView(itemView)
|
||
}
|
||
}
|
||
|
||
}
|
||
}else{// 显示扫描设备列表
|
||
startScanning()
|
||
}
|
||
|
||
|
||
}
|
||
/**
|
||
* 开始扫描设备
|
||
*/
|
||
@SuppressLint("SuspiciousIndentation")
|
||
private fun startScanning() {
|
||
if (isScanning) return
|
||
|
||
val bluetoothInfo = AndInfo.instance.bluetooth
|
||
|
||
// 显示扫描UI
|
||
isScanning = true
|
||
binding.view.visibility = View.GONE
|
||
binding.progressbar.visibility = View.VISIBLE
|
||
|
||
// 设置进度条为15秒倒计时
|
||
binding.progressItem.max = SCAN_DURATION / 1000 // 最大值为15(秒)
|
||
binding.progressItem.progress = SCAN_DURATION / 1000 // 初始进度为15(秒)
|
||
|
||
// 启动15秒进度条倒计时
|
||
startProgressCountdown()
|
||
|
||
// 开始扫描
|
||
try {
|
||
val container = binding.view as? ViewGroup
|
||
container?.let {
|
||
var list:List<DeviceInfo> = arrayListOf()
|
||
// 遍历 list,为每个设备创建 item view
|
||
// 同时扫描经典蓝牙和BLE设备
|
||
bluetoothInfo.scanNearbyDevices(
|
||
onDeviceFound = { device ->
|
||
if (!isAdded || context == null) return@scanNearbyDevices
|
||
requireActivity().runOnUiThread {
|
||
if (!isAdded || context == null) return@runOnUiThread
|
||
// 加载 item 布局
|
||
val itemView = LayoutInflater.from(requireContext())
|
||
.inflate(R.layout.item_blue_tooth, it, false)
|
||
|
||
// 设置设备信息
|
||
val tvName = itemView.findViewById<TextView>(R.id.textTitle)
|
||
val tvAddress = itemView.findViewById<TextView>(R.id.textContent)
|
||
|
||
tvName.text = device.name
|
||
tvAddress.text = device.address
|
||
// 添加到容器
|
||
it.addView(itemView)
|
||
binding.view.visibility = View.VISIBLE
|
||
binding.progressbar.visibility = View.GONE
|
||
|
||
}
|
||
},
|
||
onScanFinished = {
|
||
requireActivity().runOnUiThread {
|
||
stopScanning()
|
||
}
|
||
}
|
||
)
|
||
// 扫描BLE设备
|
||
if (bluetoothInfo.isBluetoothLeSupported) {
|
||
bluetoothInfo.scanLeDevices(
|
||
onDeviceFound = { device ->
|
||
if (!isAdded || context == null) return@scanLeDevices
|
||
requireActivity().runOnUiThread {
|
||
if (!isAdded || context == null) return@runOnUiThread
|
||
// 加载 item 布局
|
||
val itemView = LayoutInflater.from(requireContext())
|
||
.inflate(R.layout.item_blue_tooth, it, false)
|
||
|
||
// 设置设备信息
|
||
val tvName = itemView.findViewById<TextView>(R.id.textTitle)
|
||
val tvAddress = itemView.findViewById<TextView>(R.id.textContent)
|
||
|
||
tvName.text = device.name
|
||
tvAddress.text = device.address
|
||
// 添加到容器
|
||
it.addView(itemView)
|
||
binding.view.visibility = View.VISIBLE
|
||
binding.progressbar.visibility = View.GONE
|
||
}
|
||
},
|
||
durationMillis = SCAN_DURATION.toLong()
|
||
)
|
||
}
|
||
|
||
}
|
||
|
||
|
||
} catch (e: SecurityException) {
|
||
Toast.makeText(requireContext(), getString(R.string.permissions_required), Toast.LENGTH_SHORT).show()
|
||
stopScanning()
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 启动进度条倒计时
|
||
*/
|
||
private fun startProgressCountdown() {
|
||
scanTimer = object : CountDownTimer(SCAN_DURATION.toLong(), 1000) {
|
||
override fun onTick(millisUntilFinished: Long) {
|
||
val secondsLeft = millisUntilFinished / 1000
|
||
// 更新进度条(从15递减到0)
|
||
binding.progressItem.progress = secondsLeft.toInt()
|
||
}
|
||
|
||
override fun onFinish() {
|
||
// 倒计时结束,停止扫描
|
||
stopScanning()
|
||
binding.progressbar.visibility = View.GONE
|
||
}
|
||
}.start()
|
||
}
|
||
|
||
/**
|
||
* 停止扫描
|
||
*/
|
||
private fun stopScanning() {
|
||
if (!isScanning) return
|
||
|
||
isScanning = false
|
||
|
||
// 停止计时器
|
||
scanTimer?.cancel()
|
||
scanTimer = null
|
||
// 重置进度条
|
||
binding.progressItem.progress = 0
|
||
|
||
// 停止蓝牙扫描
|
||
AndInfo.instance.bluetooth.stopScan()
|
||
}
|
||
|
||
|
||
override fun onNegativeClick() {
|
||
super.onNegativeClick()
|
||
stopScanning()
|
||
|
||
}
|
||
|
||
override fun onPositiveClick() {
|
||
super.onPositiveClick()
|
||
stopScanning()
|
||
}
|
||
override fun onPause() {
|
||
super.onPause()
|
||
// 停止扫描
|
||
stopScanning()
|
||
}
|
||
} |