Android
Bluetooth und Bluetooth LE API
Suche…
Bemerkungen
Bluetooth Classic ist ab Android 2.0 (API Level 5) und höher verfügbar. Bluetooth LE ist ab Android 4.3 (API Level 18) und höher verfügbar.
Berechtigungen
Fügen Sie der Manifestdatei diese Berechtigung hinzu, um die Bluetooth-Funktionen in Ihrer Anwendung zu verwenden:
<uses-permission android:name="android.permission.BLUETOOTH" />
Wenn Sie die Geräteerkennung starten oder die Bluetooth-Einstellungen bearbeiten müssen, müssen Sie auch diese Berechtigung hinzufügen:
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
Für das Android-API-Level 23 und höher ist ein Standortzugriff erforderlich:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- OR -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
* Siehe auch die Berechtigungen Thema , um weitere Informationen darüber , wie geeignete Berechtigungen zu verwenden.
Prüfen Sie, ob Bluetooth aktiviert ist
private static final int REQUEST_ENABLE_BT = 1; // Unique request code
BluetoothAdapter mBluetoothAdapter;
// ...
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
// ...
@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_ENABLE_BT) {
if (resultCode == RESULT_OK) {
// Bluetooth was enabled
} else if (resultCode == RESULT_CANCELED) {
// Bluetooth was not enabled
}
}
}
Machen Sie das Gerät auffindbar
private static final int REQUEST_DISCOVERABLE_BT = 2; // Unique request code
private static final int DISCOVERABLE_DURATION = 120; // Discoverable duration time in seconds
// 0 means always discoverable
// maximum value is 3600
// ...
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, DISCOVERABLE_DURATION);
startActivityForResult(discoverableIntent, REQUEST_DISCOVERABLE_BT);
// ...
@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_DISCOVERABLE_BT) {
if (resultCode == RESULT_OK) {
// Device is discoverable
} else if (resultCode == RESULT_CANCELED) {
// Device is not discoverable
}
}
}
Finden Sie Bluetooth-Geräte in der Nähe
Deklarieren Sie zuerst einen BluetoothAdapter
.
BluetoothAdapter mBluetoothAdapter;
Erstellen Sie nun einen BroadcastReceiver
für ACTION_FOUND
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//Device found
if (BluetoothDevice.ACTION_FOUND.equals(action))
{
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a list
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
};
Registrieren Sie den BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
Starten Sie dann die startDiscovery
den Bluetooth-Geräten in der Nähe, indem Sie startDiscovery
aufrufen
mBluetoothAdapter.startDiscovery();
Vergessen Sie nicht, den BroadcastReceiver
in onDestroy
unregisterReceiver(mReceiver);
Verbinden Sie sich mit einem Bluetooth-Gerät
Nachdem Sie das Bluetooth-Gerät erworben haben, können Sie damit kommunizieren. Diese Art der Kommunikation erfolgt mithilfe von Socket-Input \ Output-Streams:
Dies sind die grundlegenden Schritte für die Einrichtung der Bluetooth-Kommunikation:
1) Socket initialisieren:
private BluetoothSocket _socket;
//...
public InitializeSocket(BluetoothDevice device){
try {
_socket = device.createRfcommSocketToServiceRecord(<Your app UDID>);
} catch (IOException e) {
//Error
}
}
2) An Buchse anschließen:
try {
_socket.connect();
} catch (IOException connEx) {
try {
_socket.close();
} catch (IOException closeException) {
//Error
}
}
if (_socket != null && _socket.isConnected()) {
//Socket is connected, now we can obtain our IO streams
}
3) Socket-Input \ Output-Streams erhalten
private InputStream _inStream;
private OutputStream _outStream;
//....
try {
_inStream = _socket.getInputStream();
_outStream = _socket.getOutputStream();
} catch (IOException e) {
//Error
}
Eingangsstrom - Wird als eingehender Datenkanal verwendet (Daten vom angeschlossenen Gerät empfangen)
Ausgangsstrom - Wird als ausgehender Datenkanal verwendet (Daten an angeschlossenes Gerät senden)
Nach Abschluss des dritten Schritts können wir Daten zwischen beiden Geräten mit zuvor initialisierten Streams empfangen und senden:
1) Daten empfangen (Lesen vom Socket-Eingangsstrom)
byte[] buffer = new byte[1024]; // buffer (our data)
int bytesCount; // amount of read bytes
while (true) {
try {
//reading data from input stream
bytesCount = _inStream.read(buffer);
if(buffer != null && bytesCount > 0)
{
//Parse received bytes
}
} catch (IOException e) {
//Error
}
}
2) Senden von Daten (Schreiben in den Ausgabestrom)
public void write(byte[] bytes) {
try {
_outStream.write(bytes);
} catch (IOException e) {
//Error
}
}
- Die Verbindungs-, Lese- und Schreibfunktionalität sollte natürlich in einem dedizierten Thread ausgeführt werden.
- Sockets und Stream-Objekte müssen sein
Finden Sie in der Nähe befindliche Bluetooth Low Energy-Geräte
Die BluetoothLE-API wurde in API 18 eingeführt. Die Art und Weise des Scannens von Geräten hat sich jedoch in API 21 geändert. Die Suche nach Geräten muss mit der Definition der zu untersuchenden Dienst-UUID beginnen (entweder offiziell angenommene 16-Bit-UUID oder proprietäre). . Dieses Beispiel zeigt, wie Sie eine API-unabhängige Suche nach BLE-Geräten vornehmen können:
- Erstellen Sie ein Bluetooth-Gerätemodell:
public class BTDevice {
String address;
String name;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- Definieren Sie die Bluetooth-Scanschnittstelle:
public interface ScanningAdapter {
void startScanning(String name, String[] uuids);
void stopScanning();
List<BTDevice> getFoundDeviceList();
}
- Scanfabrikklasse erstellen:
public class BluetoothScanningFactory implements ScanningAdapter {
private ScanningAdapter mScanningAdapter;
public BluetoothScanningFactory() {
if (isNewerAPI()) {
mScanningAdapter = new LollipopBluetoothLEScanAdapter();
} else {
mScanningAdapter = new JellyBeanBluetoothLEScanAdapter();
}
}
private boolean isNewerAPI() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
}
@Override
public void startScanning(String[] uuids) {
mScanningAdapter.startScanning(uuids);
}
@Override
public void stopScanning() {
mScanningAdapter.stopScanning();
}
@Override
public List<BTDevice> getFoundDeviceList() {
return mScanningAdapter.getFoundDeviceList();
}
}
- Erstellen Sie die Factory-Implementierung für jede API:
API 18:
import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.os.Build;
import android.os.Parcelable;
import android.util.Log;
import bluetooth.model.BTDevice;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public class JellyBeanBluetoothLEScanAdapter implements ScanningAdapter{
BluetoothAdapter bluetoothAdapter;
ScanCallback mCallback;
List<BTDevice> mBluetoothDeviceList;
public JellyBeanBluetoothLEScanAdapter() {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mCallback = new ScanCallback();
mBluetoothDeviceList = new ArrayList<>();
}
@Override
public void startScanning(String[] uuids) {
if (uuids == null || uuids.length == 0) {
return;
}
UUID[] uuidList = createUUIDList(uuids);
bluetoothAdapter.startLeScan(uuidList, mCallback);
}
private UUID[] createUUIDList(String[] uuids) {
UUID[] uuidList = new UUID[uuids.length];
for (int i = 0 ; i < uuids.length ; ++i) {
String uuid = uuids[i];
if (uuid == null) {
continue;
}
uuidList[i] = UUID.fromString(uuid);
}
return uuidList;
}
@Override
public void stopScanning() {
bluetoothAdapter.stopLeScan(mCallback);
}
@Override
public List<BTDevice> getFoundDeviceList() {
return mBluetoothDeviceList;
}
private class ScanCallback implements BluetoothAdapter.LeScanCallback {
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
if (isAlreadyAdded(device)) {
return;
}
BTDevice btDevice = new BTDevice();
btDevice.setName(new String(device.getName()));
btDevice.setAddress(device.getAddress());
mBluetoothDeviceList.add(btDevice);
Log.d("Bluetooth discovery", device.getName() + " " + device.getAddress());
Parcelable[] uuids = device.getUuids();
String uuid = "";
if (uuids != null) {
for (Parcelable ep : uuids) {
uuid += ep + " ";
}
Log.d("Bluetooth discovery", device.getName() + " " + device.getAddress() + " " + uuid);
}
}
private boolean isAlreadyAdded(BluetoothDevice bluetoothDevice) {
for (BTDevice device : mBluetoothDeviceList) {
String alreadyAddedDeviceMACAddress = device.getAddress();
String newDeviceMACAddress = bluetoothDevice.getAddress();
if (alreadyAddedDeviceMACAddress.equals(newDeviceMACAddress)) {
return true;
}
}
return false;
}
}
}
API 21:
import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.os.Build;
import android.os.ParcelUuid;
import bluetooth.model.BTDevice;
import java.util.ArrayList;
import java.util.List;
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class LollipopBluetoothLEScanAdapter implements ScanningAdapter {
BluetoothLeScanner bluetoothLeScanner;
ScanCallback mCallback;
List<BTDevice> mBluetoothDeviceList;
public LollipopBluetoothLEScanAdapter() {
bluetoothLeScanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();
mCallback = new ScanCallback();
mBluetoothDeviceList = new ArrayList<>();
}
@Override
public void startScanning(String[] uuids) {
if (uuids == null || uuids.length == 0) {
return;
}
List<ScanFilter> filterList = createScanFilterList(uuids);
ScanSettings scanSettings = createScanSettings();
bluetoothLeScanner.startScan(filterList, scanSettings, mCallback);
}
private List<ScanFilter> createScanFilterList(String[] uuids) {
List<ScanFilter> filterList = new ArrayList<>();
for (String uuid : uuids) {
ScanFilter filter = new ScanFilter.Builder()
.setServiceUuid(ParcelUuid.fromString(uuid))
.build();
filterList.add(filter);
};
return filterList;
}
private ScanSettings createScanSettings() {
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_BALANCED)
.build();
return settings;
}
@Override
public void stopScanning() {
bluetoothLeScanner.stopScan(mCallback);
}
@Override
public List<BTDevice> getFoundDeviceList() {
return mBluetoothDeviceList;
}
public class ScanCallback extends android.bluetooth.le.ScanCallback {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
if (result == null) {
return;
}
BTDevice device = new BTDevice();
device.setAddress(result.getDevice().getAddress());
device.setName(new StringBuffer(result.getScanRecord().getDeviceName()).toString());
if (device == null || device.getAddress() == null) {
return;
}
if (isAlreadyAdded(device)) {
return;
}
mBluetoothDeviceList.add(device);
}
private boolean isAlreadyAdded(BTDevice bluetoothDevice) {
for (BTDevice device : mBluetoothDeviceList) {
String alreadyAddedDeviceMACAddress = device.getAddress();
String newDeviceMACAddress = bluetoothDevice.getAddress();
if (alreadyAddedDeviceMACAddress.equals(newDeviceMACAddress)) {
return true;
}
}
return false;
}
}
}
Erhalten Sie die Liste der gefundenen Geräte durch Anrufen:
scanningFactory.startScanning({uuidlist}); wait few seconds... List<BTDevice> bluetoothDeviceList = scanningFactory.getFoundDeviceList();