# 蓝牙权限申请指南 ## 🔐 权限说明 在Android 12及以上版本,使用蓝牙功能需要动态申请以下权限: ### 必需权限 1. **BLUETOOTH_SCAN** - 扫描蓝牙设备 2. **BLUETOOTH_CONNECT** - 连接蓝牙设备 3. **ACCESS_FINE_LOCATION** - 精确位置(蓝牙扫描需要) 4. **ACCESS_COARSE_LOCATION** - 粗略位置(蓝牙扫描需要) ## 📱 权限申请流程 ### 首次启动应用 1. 应用启动时会显示当前权限状态 2. 点击"连接蓝牙"按钮 3. 系统弹出权限申请对话框 4. 选择"允许"授予所有权限 ### 权限状态显示 ``` 权限状态: BLUETOOTH_SCAN: ✓ BLUETOOTH_CONNECT: ✓ ACCESS_FINE_LOCATION: ✓ ACCESS_COARSE_LOCATION: ✓ ``` ## ⚠️ 常见问题 ### 1. 权限被拒绝 **症状**:按钮显示"权限被拒绝",无法使用蓝牙功能 **解决**: - 进入系统设置 → 应用管理 → 本应用 → 权限 - 手动开启蓝牙和位置权限 - 重新启动应用 ### 2. 部分权限缺失 **症状**:提示"缺少权限: BLUETOOTH_SCAN, ACCESS_FINE_LOCATION" **解决**: - 确保所有4个权限都已授予 - 位置权限对于蓝牙扫描是必需的 ### 3. 权限申请对话框不出现 **症状**:点击按钮无反应 **解决**: - 检查应用是否被系统限制 - 重启应用或设备 - 检查系统版本是否支持 ## 🔧 技术实现 ### 权限检查代码 ```kotlin private fun checkAndRequestPermissions(): Boolean { val missingPermissions = mutableListOf() for (permission in REQUIRED_PERMISSIONS) { if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { missingPermissions.add(permission) } } if (missingPermissions.isNotEmpty()) { updateStatus("需要蓝牙权限: ${missingPermissions.joinToString(", ")}") ActivityCompat.requestPermissions( this, missingPermissions.toTypedArray(), PERMISSION_REQUEST_CODE ) return false } return true } ``` ### 权限结果处理 ```kotlin override fun onRequestPermissionsResult( requestCode: Int, permissions: Array, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) when (requestCode) { PERMISSION_REQUEST_CODE -> { val allGranted = grantResults.all { it == PackageManager.PERMISSION_GRANTED } if (allGranted) { updateStatus("蓝牙权限已授予,开始扫描...") startBluetoothScan() } else { updateStatus("蓝牙权限被拒绝,无法使用蓝牙功能") binding.bluetoothButton.text = "权限被拒绝" binding.bluetoothButton.setBackgroundColor(Color.parseColor("#9E9E9E")) } } } } ``` ## 📋 权限清单 ### AndroidManifest.xml ```xml ``` ### MainActivity.kt ```kotlin companion object { private const val PERMISSION_REQUEST_CODE = 1001 private val REQUIRED_PERMISSIONS = arrayOf( Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION ) // Used to load the 'cmake_project_test' library on application startup. init { System.loadLibrary("cmake_project_test") } } ``` ## 🎯 最佳实践 ### 1. 权限申请时机 - 在用户主动点击蓝牙功能时申请 - 避免应用启动时强制申请 - 提供清晰的权限用途说明 ### 2. 用户体验 - 显示当前权限状态 - 提供权限被拒绝时的解决方案 - 友好的错误提示 ### 3. 兼容性 - 支持Android 6.0+的动态权限 - 兼容Android 12+的新蓝牙权限 - 处理权限被拒绝的情况 ## 🔍 调试技巧 ### 检查权限状态 ```kotlin private fun checkPermissionStatus(): String { val status = mutableListOf() for (permission in REQUIRED_PERMISSIONS) { val granted = ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED status.add("${permission.split(".").last()}: ${if (granted) "✓" else "✗"}") } return status.joinToString("\n") } ``` ### 日志输出 - 权限申请过程会记录详细日志 - 可通过Logcat查看权限状态变化 - 便于调试权限相关问题 ## 📝 注意事项 1. **位置权限必需**:蓝牙扫描需要位置权限,这是系统要求 2. **权限持久性**:权限一旦授予,应用重启后仍然有效 3. **系统限制**:某些系统可能限制权限申请 4. **版本兼容**:不同Android版本的权限要求可能不同