Crear una aplicación para Android que permita recibir mensajes por Bluetooth

Código de la aplicación
AndroidManifest.xml
[crayon-6a616ce5cf98c009786486/]
MainActivity.kt
[crayon-6a616ce5cf993831633967/]
build.gradle.kts
[crayon-6a616ce5cf99a487814098/]
Resultado de la ejecución de la aplicación

Explicación del código
1. Definición de UUIDs y Variables
private val SERVICE_UUID = UUID.fromString("12345678-1234-5678-1234-56789abcdef0")
private val CHARACTERISTIC_UUID = UUID.fromString("abcdef01-2345-6789-abcd-ef0123456789")
SERVICE_UUID: UUID para el servicio BLE.CHARACTERISTIC_UUID: UUID para la característica BLE que permite leer y escribir datos.
2. Declaración de Variables
private lateinit var bluetoothManager: BluetoothManager
private lateinit var bluetoothAdapter: BluetoothAdapter
private var bluetoothGattServer: BluetoothGattServer? = null
private var bluetoothLeAdvertiser: BluetoothLeAdvertiser? = null
private var receivedData by mutableStateOf("No data received")
private var connectionInfo by mutableStateOf("No device connected")
bluetoothManagerybluetoothAdapter: Para manejar Bluetooth.bluetoothGattServer: El servidor GATT que manejará las solicitudes de otros dispositivos.bluetoothLeAdvertiser: Para la publicidad BLE.receivedDatayconnectionInfo: Estados que almacenan la información de los datos recibidos y la conexión actual.
3. Método onCreate
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
BluetoothPeripheralApp(receivedData, connectionInfo)
}
checkPermissions()
setupBluetooth()
startGattServer()
startAdvertising()
}
setContent: Configura la interfaz de usuario usando Jetpack Compose.checkPermissions: Verifica y solicita permisos necesarios para Bluetooth.setupBluetooth: Inicializa elBluetoothManageryBluetoothAdapter.startGattServer: Inicia el servidor GATT para manejar solicitudes.startAdvertising: Comienza a anunciar el dispositivo para que otros puedan encontrarlo.
4. Método onDestroy
override fun onDestroy() {
super.onDestroy()
bluetoothGattServer?.close()
}
- Cierra el servidor GATT cuando la actividad se destruye.
5. Método checkPermissions
private fun checkPermissions() {
val permissions = arrayOf(
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_CONNECT,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_ADVERTISE
)
if (permissions.any { ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED }) {
ActivityCompat.requestPermissions(this, permissions, 1)
}
}
- Verifica si se tienen los permisos necesarios para usar Bluetooth. Si no, solicita permisos al usuario.
6. Método setupBluetooth
private fun setupBluetooth() {
bluetoothManager = getSystemService(BLUETOOTH_SERVICE) as BluetoothManager
bluetoothAdapter = bluetoothManager.adapter
}
- Inicializa el
BluetoothManagery elBluetoothAdapter, que son necesarios para la operación de Bluetooth.
7. Método startGattServer
@SuppressLint("MissingPermission")
private fun startGattServer() {
bluetoothGattServer = bluetoothManager.openGattServer(this, object : BluetoothGattServerCallback() {
override fun onConnectionStateChange(device: BluetoothDevice, status: Int, newState: Int) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
connectionInfo = "Connected to ${device.name ?: "Unknown"} (${device.address})"
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
connectionInfo = "Disconnected from device"
}
}
override fun onServiceAdded(status: Int, service: BluetoothGattService) {
if (status == BluetoothGatt.GATT_SUCCESS) {
// Handle service added
}
}
override fun onCharacteristicReadRequest(device: BluetoothDevice, requestId: Int, offset: Int, characteristic: BluetoothGattCharacteristic) {
if (characteristic.uuid == CHARACTERISTIC_UUID) {
bluetoothGattServer?.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, characteristic.value)
}
}
override fun onCharacteristicWriteRequest(device: BluetoothDevice, requestId: Int, characteristic: BluetoothGattCharacteristic, preparedWrite: Boolean, responseNeeded: Boolean, offset: Int, value: ByteArray) {
if (characteristic.uuid == CHARACTERISTIC_UUID) {
receivedData = String(value, Charsets.UTF_8)
if (responseNeeded) {
bluetoothGattServer?.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, null)
}
}
}
})
val service = BluetoothGattService(SERVICE_UUID, BluetoothGattService.SERVICE_TYPE_PRIMARY)
val characteristic = BluetoothGattCharacteristic(
CHARACTERISTIC_UUID,
BluetoothGattCharacteristic.PROPERTY_READ or BluetoothGattCharacteristic.PROPERTY_WRITE,
BluetoothGattCharacteristic.PERMISSION_READ or BluetoothGattCharacteristic.PERMISSION_WRITE
)
service.addCharacteristic(characteristic)
bluetoothGattServer?.addService(service)
}
onConnectionStateChange: Actualiza la información de conexión cuando un dispositivo se conecta o desconecta.onServiceAdded: Maneja el estado cuando un servicio se agrega.onCharacteristicReadRequest: Responde a las solicitudes de lectura de la característica.onCharacteristicWriteRequest: ActualizareceivedDatacon el valor recibido cuando se escribe en la característica.
8. Método startAdvertising
@SuppressLint("MissingPermission")
private fun startAdvertising() {
bluetoothLeAdvertiser = bluetoothAdapter.bluetoothLeAdvertiser
if (bluetoothLeAdvertiser == null) {
println("Bluetooth LE Advertiser not available.")
return
}
val advertisingSettings = AdvertiseSettings.Builder()
.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH)
.setConnectable(true)
.build()
val advertisingData = AdvertiseData.Builder()
.setIncludeDeviceName(true)
.addServiceUuid(ParcelUuid(SERVICE_UUID))
.build()
bluetoothLeAdvertiser?.startAdvertising(advertisingSettings, advertisingData, object : AdvertiseCallback() {
override fun onStartSuccess(settingsInEffect: AdvertiseSettings) {
super.onStartSuccess(settingsInEffect)
println("Advertising started successfully")
}
override fun onStartFailure(errorCode: Int) {
super.onStartFailure(errorCode)
println("Advertising failed with error code $errorCode")
}
})
}
- Configura y comienza a anunciar el servicio BLE. Esto hace que el dispositivo sea detectable y accesible para otros dispositivos BLE.
9. Método BluetoothPeripheralApp
@Composable
fun BluetoothPeripheralApp(receivedData: String, connectionInfo: String) {
Column(modifier = Modifier.padding(16.dp)) {
Text("Received Messages:")
Spacer(modifier = Modifier.height(8.dp))
Text(receivedData)
Spacer(modifier = Modifier.height(16.dp))
Text("Connection Info:")
Spacer(modifier = Modifier.height(8.dp))
Text(connectionInfo)
}
}
- Define la interfaz de usuario usando Jetpack Compose. Muestra los datos recibidos y la información de conexión.