Bluetooth
Bluetooth, din perspectiva dezvoltării pe Android, reprezintă o tehnologie wireless esențială care permite dispozitivelor să comunice între ele pe distanțe scurte. Android oferă un API extins pentru Bluetooth, care permite dezvoltatorilor să realizeze diverse funcționalități, de la transferul simplu de date până la gestionarea conexiunilor complexe între dispozitive.
API-ul Bluetooth în Android este împărțit în două categorii principale:
-
Bluetooth clasic - Este folosit pentru comunicarea punct-la-punct între dispozitive, ideal pentru transferul de date la volum mare, cum ar fi fișierele audio sau datele de pe un dispozitiv periferic. Este utilizat frecvent în cazul căștilor, difuzoarelor și al altor dispozitive periferice.
-
Bluetooth Low Energy (BLE) - Cunoscut și sub numele de Bluetooth 4.0+, este optimizat pentru consum redus de energie, fiind ideal pentru dispozitivele și senzorii care necesită transferuri de date mici și ocazionale. BLE este utilizat adesea în dispozitive wearable, dispozitive de urmărire a fitnessului și alte gadgeturi inteligente.
API-ul Android pentru Bluetooth permite dezvoltatorilor să execute o serie de acțiuni, inclusiv:
- Scanarea dispozitivelor Bluetooth din apropiere și afișarea informațiilor despre acestea.
- Inițializarea conexiunilor între dispozitive și gestionarea datelor transmise.
- Crearea unui server Bluetooth pe dispozitiv, care poate accepta conexiuni de la alte dispozitive.
- Gestionarea dispozitivelor asociate și păstrarea unei liste a dispozitivelor cunoscute.
- Comunicarea cu profiluri Bluetooth specifice, cum ar fi A2DP (Advanced Audio Distribution Profile) pentru transmiterea audio sau HFP (Hands-Free Profile) pentru apeluri telefonice.
Pentru a utiliza Bluetooth în aplicațiile Android, dezvoltatorii trebuie să includă permisiunile necesare în fișierul manifest al aplicației și, în cazul accesului la BLE, să verifice dacă dispozitivul suportă BLE.
Pentru a utiliza funcționalitatea Bluetooth, va trebui să adăugați următoarele permisiuni în fișierul AndroidManifest.xml:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
Exemplu de cum se cer permisiunile in Android:
List<String> permissions = new ArrayList<>();
permissions.add(Manifest.permission.BLUETOOTH_CONNECT);
permissions.add(Manifest.permission.BLUETOOTH_SCAN);
// Cerem permisiunile utilizatorului
ActivityCompat.requestPermissions(this, permissions.toArray(new String[0]), REQUEST_PERMISSIONS);
val permissions = mutableListOf<String>()
permissions.add(Manifest.permission.BLUETOOTH_CONNECT)
permissions.add(Manifest.permission.BLUETOOTH_SCAN)
// Cerem permisiunile utilizatorului
ActivityCompat.requestPermissions(this, permissions.toTypedArray(), REQUEST_PERMISSIONS)
BlueetoothAdapter
BluetoothAdapter este punctul central pentru toate operațiunile Bluetooth. Acesta:
- Permite activarea și dezactivarea Bluetooth.
- Inițiază procesul de descoperire a dispozitivelor din apropiere.
- Listează dispozitivele asociate anterior.
Exemplu de activare a Bluetooth:
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
// Dispozitivul nu suportă Bluetooth
} else if (!bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
if (bluetoothAdapter == null) {
// Dispozitivul nu suportă Bluetooth
} else if (!bluetoothAdapter.isEnabled) {
val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT)
}
Descoperirea dispozitivelor
Pentru a găsi alte dispozitive Bluetooth din apropiere, folosim metoda startDiscovery() din BluetoothAdapter. Este necesar să înregistrați un BroadcastReceiver pentru a primi informații despre dispozitivele descoperite.
Exemplu:
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(receiver, filter);
bluetoothAdapter.startDiscovery();
val filter = IntentFilter(BluetoothDevice.ACTION_FOUND)
registerReceiver(receiver, filter)
bluetoothAdapter.startDiscovery()
Etapele conectării dispozitivelor
După ce am descoperit alte dispozitive, vom crea o conexiune între dispozitivele noastre, folosind clasele BluetoothServerSocket BluetoothSocket.
1. Configurarea unui server Bluetooth
Serverul este responsabil de acceptarea conexiunilor inițiate de alte dispozitive. Acest lucru se face utilizând un BluetoothServerSocket.
Pentru a crea un server socket, folosim metoda listenUsingRfcommWithServiceRecord a clasei BluetoothAdapter. Aceasta creează un BluetoothServerSocket, care poate asculta conexiunile.
Exemplu de configurare:
BluetoothServerSocket serverSocket = null;
try {
serverSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord(
"BluetoothChatApp", // Numele serviciului
MY_UUID // UUID-ul unic care identifică serviciul
);
} catch (IOException e) {
Log.e("ServerSocket", "Eroare la crearea server socket: " + e.getMessage());
}
var serverSocket: BluetoothServerSocket? = null
try {
serverSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord(
"BluetoothChatApp", // Numele serviciului
MY_UUID // UUID-ul unic care identifică serviciul
)
} catch (e: IOException) {
Log.e("ServerSocket", "Eroare la crearea server socket: ${e.message}")
}
2. Acceptarea unei conexiuni
După ce serverul a fost configurat, utilizăm metoda accept() pentru a aștepta și accepta conexiunile de la alte dispozitive.
Exemplu:
BluetoothSocket socket = null;
try {
// Metoda accept() este blocantă până când un dispozitiv se conectează
socket = serverSocket.accept();
} catch (IOException e) {
Log.e("ServerSocket", "Eroare la acceptarea conexiunii: " + e.getMessage());
}
var socket: BluetoothSocket? = null
try {
// Metoda accept() este blocantă până când un dispozitiv se conectează
socket = serverSocket.accept()
} catch (e: IOException) {
Log.e("ServerSocket", "Eroare la acceptarea conexiunii: ${e.message}")
}
3. Inițierea conexiunii ca dispozitiv client
Dispozitivul client utilizează un BluetoothSocket pentru a iniția o conexiune către server.
Pentru a crea un socket pentru client, utilizăm metoda createRfcommSocketToServiceRecord a clasei BluetoothDevice pentru a crea canalul de comunicatie.
Exemplu:
BluetoothSocket clientSocket = null;
try {
clientSocket = bluetoothDevice.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Log.e("ClientSocket", "Eroare la crearea socket-ului: " + e.getMessage());
}
var clientSocket: BluetoothSocket? = null
try {
clientSocket = bluetoothDevice.createRfcommSocketToServiceRecord(MY_UUID)
} catch (e: IOException) {
Log.e("ClientSocket", "Eroare la crearea socket-ului: ${e.message}")
}
4. Conectarea la server
Odată creat socket-ul, folosim metoda connect() pentru a iniția conexiunea către server.
Exemplu:
try {
clientSocket.connect();
} catch (IOException e) {
Log.e("ClientSocket", "Eroare la conectare: " + e.getMessage());
try {
clientSocket.close(); // Închidem socket-ul în caz de eroare
} catch (IOException closeException) {
Log.e("ClientSocket", "Eroare la închiderea socket-ului: " + closeException.getMessage());
}
}
try {
clientSocket.connect()
} catch (e: IOException) {
Log.e("ClientSocket", "Eroare la conectare: ${e.message}")
try {
clientSocket.close() // Închidem socket-ul în caz de eroare
} catch (closeException: IOException) {
Log.e("ClientSocket", "Eroare la închiderea socket-ului: ${closeException.message}")
}
}
Important:
Înainte de a apela metoda connect(), este recomandat să oprim descoperirea dispozitivelor (folosind bluetoothAdapter.cancelDiscovery()) pentru a evita interferențele.
5. Comunicarea între dispozitive
După ce conexiunea a fost stabilită cu succes (atât pe server, cât și pe client), putem utiliza obiectul BluetoothSocket pentru a trimite și primi date.
Obtinerea fluxului de intrare InputStream pentru citirea datelor:
InputStream inputStream = socket.getInputStream();
val inputStream = socket.getInputStream()
Obtinerea fluxului de iesire OutputStream pentru trimiterea datelor:
OutputStream outputStream = socket.getOutputStream();
val outputStream = socket.getOutputStream()
Exemplu trimitere date:
OutputStream outputStream = socket.getOutputStream();
outputStream.write("Mesaj de test".getBytes());
val outputStream = socket.getOutputStream()
outputStream.write("Mesaj de test".toByteArray())
Exemplu primire date:
InputStream inputStream = socket.getInputStream();
byte[] buffer = new byte[1024];
int bytes = inputStream.read(buffer);
String message = new String(buffer, 0, bytes);
val inputStream = socket.getInputStream()
val buffer = ByteArray(1024)
val bytes = inputStream.read(buffer)
val message = String(buffer, 0, bytes)